Compare commits

..
Author SHA1 Message Date
Maxime Beauchemin 29fd4a3094 clarifying messages, removing some useless output 2024-12-15 23:17:33 -08:00
Maxime Beauchemin cd6cc34735 chore: set dev env logging level to INFO (from DEBUG)
Using a higher logging default in dev mode to clean up output. Also setting so TMI messages to debug to prevent not-so-useful information to show up on startup.

Devs can easily switch the logging level to DEBUG if/when needed.
2024-12-15 22:55:47 -08:00
494 changed files with 2539 additions and 4870 deletions
-1
View File
@@ -72,7 +72,6 @@ github:
- cypress-matrix (3, chrome) - cypress-matrix (3, chrome)
- cypress-matrix (4, chrome) - cypress-matrix (4, chrome)
- cypress-matrix (5, chrome) - cypress-matrix (5, chrome)
- dependency-review
- frontend-build - frontend-build
- pre-commit (current) - pre-commit (current)
- pre-commit (next) - pre-commit (next)
-1
View File
@@ -42,7 +42,6 @@ docs/
install/ install/
superset-frontend/cypress-base/ superset-frontend/cypress-base/
superset-frontend/coverage/ superset-frontend/coverage/
superset-frontend/.temp_cache/
superset/static/assets/ superset/static/assets/
superset-websocket/dist/ superset-websocket/dist/
venv venv
+4 -4
View File
@@ -16,17 +16,17 @@
# Notify E2E test maintainers of changes # Notify E2E test maintainers of changes
/superset-frontend/cypress-base/ @sadpandajoe @geido @eschutho @rusackas @betodealmeida /superset-frontend/cypress-base/ @jinghua-qa @geido @eschutho @rusackas @betodealmeida
# Notify PMC members of changes to GitHub Actions # Notify PMC members of changes to GitHub Actions
/.github/ @villebro @geido @eschutho @rusackas @betodealmeida @nytai @mistercrunch @craig-rueda @kgabryje @dpgaspar /.github/ @villebro @geido @eschutho @rusackas @betodealmeida @nytai @mistercrunch @craig-rueda @john-bodley @kgabryje @dpgaspar
# Notify PMC members of changes to required GitHub Actions # Notify PMC members of changes to required GitHub Actions
/.asf.yaml @villebro @geido @eschutho @rusackas @betodealmeida @nytai @mistercrunch @craig-rueda @kgabryje @dpgaspar /.asf.yaml @villebro @geido @eschutho @rusackas @betodealmeida @nytai @mistercrunch @craig-rueda @john-bodley @kgabryje @dpgaspar
# Maps are a finicky contribution process we care about # Maps are a finnicky contribution process we care about
**/*.geojson @villebro @rusackas **/*.geojson @villebro @rusackas
/superset-frontend/plugins/legacy-plugin-chart-country-map/ @villebro @rusackas /superset-frontend/plugins/legacy-plugin-chart-country-map/ @villebro @rusackas
-3
View File
@@ -44,13 +44,10 @@ runs:
if [ "${{ inputs.install-superset }}" = "true" ]; then if [ "${{ inputs.install-superset }}" = "true" ]; then
sudo apt-get update && sudo apt-get -y install libldap2-dev libsasl2-dev sudo apt-get update && sudo apt-get -y install libldap2-dev libsasl2-dev
pip install --upgrade pip setuptools wheel uv pip install --upgrade pip setuptools wheel uv
if [ "${{ inputs.requirements-type }}" = "dev" ]; then if [ "${{ inputs.requirements-type }}" = "dev" ]; then
uv pip install --system -r requirements/development.txt uv pip install --system -r requirements/development.txt
elif [ "${{ inputs.requirements-type }}" = "base" ]; then elif [ "${{ inputs.requirements-type }}" = "base" ]; then
uv pip install --system -r requirements/base.txt uv pip install --system -r requirements/base.txt
fi fi
uv pip install --system -e .
fi fi
shell: bash shell: bash
-69
View File
@@ -1,69 +0,0 @@
name: "Setup Docker Environment"
description: "Reusable steps for setting up QEMU, Docker Buildx, DockerHub login, Supersetbot, and optionally Docker Compose"
inputs:
build:
description: "Used for building?"
required: false
default: "false"
dockerhub-user:
description: "DockerHub username"
required: false
dockerhub-token:
description: "DockerHub token"
required: false
install-docker-compose:
description: "Flag to install Docker Compose"
required: false
default: "true"
login-to-dockerhub:
description: "Whether you want to log into dockerhub"
required: false
default: "true"
outputs: {}
runs:
using: "composite"
steps:
- name: Set up QEMU
if: ${{ inputs.build == 'true' }}
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
if: ${{ inputs.build == 'true' }}
uses: docker/setup-buildx-action@v3
- name: Try to login to DockerHub
if: ${{ inputs.login-to-dockerhub == 'true' }}
continue-on-error: true
uses: docker/login-action@v3
with:
username: ${{ inputs.dockerhub-user }}
password: ${{ inputs.dockerhub-token }}
- name: Install Docker Compose
if: ${{ inputs.install-docker-compose == 'true' }}
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
# Download and save the Docker GPG key in the correct format
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Ensure the key file is readable
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the Docker repository using the correct key
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update package lists and install Docker Compose plugin
sudo apt update
sudo apt install -y docker-compose-plugin
- name: Docker Version Info
shell: bash
run: docker info
+2 -1
View File
@@ -22,7 +22,8 @@ updates:
# - package-ecosystem: "pip" # - package-ecosystem: "pip"
# NOTE: as dependabot isn't compatible with our usage of `uv pip compile` we're using # NOTE: as dependabot isn't compatible with our python
# dependency setup (pip-compile-multi), we'll be using
# `supersetbot` instead # `supersetbot` instead
- package-ecosystem: "npm" - package-ecosystem: "npm"
+3 -3
View File
@@ -23,7 +23,7 @@ on:
jobs: jobs:
bump-python-package: bump-python-package:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
actions: write actions: write
contents: write contents: write
@@ -45,8 +45,8 @@ jobs:
with: with:
python-version: "3.10" python-version: "3.10"
- name: Install uv - name: Install pip-compile-multi
run: pip install uv run: pip install pip-compile-multi
- name: supersetbot bump-python -p "${{ github.event.inputs.package }}" - name: supersetbot bump-python -p "${{ github.event.inputs.package }}"
env: env:
+1 -1
View File
@@ -9,7 +9,7 @@ on:
jobs: jobs:
cancel-duplicate-runs: cancel-duplicate-runs:
name: Cancel duplicate workflow runs name: Cancel duplicate workflow runs
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
actions: write actions: write
contents: read contents: read
-44
View File
@@ -1,44 +0,0 @@
name: Check python dependencies
on:
push:
branches:
- "master"
- "[0-9].[0-9]*"
pull_request:
types: [synchronize, opened, reopened, ready_for_review]
# cancel previous workflow jobs for PRs
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
jobs:
check-python-deps:
runs-on: ubuntu-22.04
steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4
with:
persist-credentials: false
submodules: recursive
depth: 1
- name: Setup Python
if: steps.check.outputs.python
uses: ./.github/actions/setup-backend/
- name: Run uv
if: steps.check.outputs.python
run: ./scripts/uv-pip-compile.sh
- name: Check for uncommitted changes
run: |
if [[ -n "$(git diff)" ]]; then
echo "ERROR: The pinned dependencies are not up-to-date."
echo "Please run './scripts/uv-pip-compile.sh' and commit the changes."
exit 1
else
echo "Pinned dependencies are up-to-date."
fi
@@ -19,7 +19,7 @@ concurrency:
jobs: jobs:
check_db_migration_conflict: check_db_migration_conflict:
name: Check DB migration conflict name: Check DB migration conflict
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
+1 -1
View File
@@ -17,7 +17,7 @@ concurrency:
jobs: jobs:
analyze: analyze:
name: Analyze name: Analyze
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
actions: read actions: read
contents: read contents: read
+2 -35
View File
@@ -5,26 +5,14 @@
# Source repository: https://github.com/actions/dependency-review-action # Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: "Dependency Review" name: "Dependency Review"
on: on: [pull_request]
push:
branches:
- "master"
- "[0-9].[0-9]*"
pull_request:
types: [synchronize, opened, reopened, ready_for_review]
# cancel previous workflow jobs for PRs
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
permissions: permissions:
contents: read contents: read
jobs: jobs:
dependency-review: dependency-review:
if: github.event_name == 'pull_request' runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps: steps:
- name: "Checkout Repository" - name: "Checkout Repository"
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -45,24 +33,3 @@ jobs:
# pkg:npm/node-forge@1.3.1 # pkg:npm/node-forge@1.3.1
# selecting BSD-3-Clause licensing terms for node-forge to ensure compatibility with Apache # 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, pkg:npm/rgbcolor, pkg:npm/jszip@3.10.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, pkg:npm/jszip@3.10.1
python-dependency-liccheck:
runs-on: ubuntu-22.04
steps:
- name: "Checkout Repository"
uses: actions/checkout@v4
- name: Setup Python
uses: ./.github/actions/setup-backend/
with:
requirements-type: base
- name: "Set up liccheck"
run: |
uv pip install --system liccheck
- name: "Run liccheck"
run: |
# run the checks
liccheck -R output.txt
# Print the report
cat output.txt
+16 -31
View File
@@ -15,20 +15,20 @@ concurrency:
jobs: jobs:
setup_matrix: setup_matrix:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
outputs: outputs:
matrix_config: ${{ steps.set_matrix.outputs.matrix_config }} matrix_config: ${{ steps.set_matrix.outputs.matrix_config }}
steps: steps:
- id: set_matrix - id: set_matrix
run: | run: |
MATRIX_CONFIG=$(if [ "${{ github.event_name }}" == "pull_request" ]; then echo '["dev", "lean"]'; else echo '["dev", "lean", "py310", "websocket", "dockerize", "py311"]'; 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 "matrix_config=${MATRIX_CONFIG}" >> $GITHUB_OUTPUT
echo $GITHUB_OUTPUT echo $GITHUB_OUTPUT
docker-build: docker-build:
name: docker-build name: docker-build
needs: setup_matrix needs: setup_matrix
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
build_preset: ${{fromJson(needs.setup_matrix.outputs.matrix_config)}} build_preset: ${{fromJson(needs.setup_matrix.outputs.matrix_config)}}
@@ -50,13 +50,21 @@ jobs:
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Docker Environment - name: Set up QEMU
if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
uses: ./.github/actions/setup-docker uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
uses: docker/setup-buildx-action@v3
- name: Try to login to DockerHub
if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
continue-on-error: true
uses: docker/login-action@v3
with: with:
dockerhub-user: ${{ secrets.DOCKERHUB_USER }} username: ${{ secrets.DOCKERHUB_USER }}
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
build: "true"
- name: Setup supersetbot - name: Setup supersetbot
if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
@@ -76,30 +84,7 @@ jobs:
fi fi
supersetbot docker \ supersetbot docker \
--push \
--preset ${{ matrix.build_preset }} \ --preset ${{ matrix.build_preset }} \
--context "$EVENT" \ --context "$EVENT" \
--context-ref "$RELEASE" $FORCE_LATEST \ --context-ref "$RELEASE" $FORCE_LATEST \
--extra-flags "--build-arg INCLUDE_CHROMIUM=false" \
$PLATFORM_ARG $PLATFORM_ARG
- name: Docker pull
if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
run: docker pull apache/superset:GHA-${GITHUB_RUN_ID}
- name: Print docker stats
if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
run: |
IMAGE_ID=$(docker images --filter "label=sha=${{ github.sha }}" --format "{{.ID}}" | head -n 1)
echo "SHA: ${{ github.sha }}"
echo "IMAGE: $IMAGE_ID"
docker images $IMAGE_ID
docker history $IMAGE_ID
- name: docker-compose sanity check
if: (steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker) && (matrix.build_preset == 'dev' || matrix.build_preset == 'lean')
shell: bash
run: |
export SUPERSET_BUILD_TARGET=${{ matrix.build_preset }}
docker compose build superset-init --build-arg DEV_MODE=false --build-arg INCLUDE_CHROMIUM=false
docker compose up superset-init --exit-code-from superset-init
+2 -2
View File
@@ -8,7 +8,7 @@ on:
jobs: jobs:
config: config:
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
outputs: outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }} has-secrets: ${{ steps.check.outputs.has-secrets }}
steps: steps:
@@ -23,7 +23,7 @@ jobs:
build: build:
needs: config needs: config
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
defaults: defaults:
run: run:
working-directory: superset-embedded-sdk working-directory: superset-embedded-sdk
+1 -1
View File
@@ -13,7 +13,7 @@ concurrency:
jobs: jobs:
embedded-sdk-test: embedded-sdk-test:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
defaults: defaults:
run: run:
working-directory: superset-embedded-sdk working-directory: superset-embedded-sdk
+2 -2
View File
@@ -6,7 +6,7 @@ on:
jobs: jobs:
config: config:
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
outputs: outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }} has-secrets: ${{ steps.check.outputs.has-secrets }}
steps: steps:
@@ -22,7 +22,7 @@ jobs:
needs: config needs: config
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
name: Cleanup ephemeral envs name: Cleanup ephemeral envs
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
pull-requests: write pull-requests: write
steps: steps:
+19 -15
View File
@@ -21,15 +21,12 @@ jobs:
group: ${{ github.workflow }}-${{ github.event.inputs.issue_number || github.event.issue.number || github.run_id }}-comment group: ${{ github.workflow }}-${{ github.event.inputs.issue_number || github.event.issue.number || github.run_id }}-comment
cancel-in-progress: true cancel-in-progress: true
name: Evaluate ephemeral env comment trigger (/testenv) name: Evaluate ephemeral env comment trigger (/testenv)
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
pull-requests: write pull-requests: write
outputs: outputs:
slash-command: ${{ steps.eval-body.outputs.result }} slash-command: ${{ steps.eval-body.outputs.result }}
feature-flags: ${{ steps.eval-feature-flags.outputs.result }} feature-flags: ${{ steps.eval-feature-flags.outputs.result }}
env:
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
steps: steps:
- name: Debug - name: Debug
@@ -115,7 +112,7 @@ jobs:
needs: ephemeral-env-comment needs: ephemeral-env-comment
if: needs.ephemeral-env-comment.outputs.slash-command == 'up' if: needs.ephemeral-env-comment.outputs.slash-command == 'up'
name: ephemeral-docker-build name: ephemeral-docker-build
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: Get Info from comment - name: Get Info from comment
uses: actions/github-script@v7 uses: actions/github-script@v7
@@ -142,24 +139,31 @@ jobs:
ref: ${{ steps.get-sha.outputs.sha }} ref: ${{ steps.get-sha.outputs.sha }}
persist-credentials: false persist-credentials: false
- name: Setup Docker Environment - name: Set up QEMU
uses: ./.github/actions/setup-docker uses: docker/setup-qemu-action@v3
with:
dockerhub-user: ${{ secrets.DOCKERHUB_USER }} - name: Set up Docker Buildx
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} uses: docker/setup-buildx-action@v3
build: "true"
install-docker-compose: "false"
- name: Setup supersetbot - name: Setup supersetbot
uses: ./.github/actions/setup-supersetbot/ uses: ./.github/actions/setup-supersetbot/
- name: Try to login to DockerHub
if: steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker
continue-on-error: true
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build ephemeral env image - name: Build ephemeral env image
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
run: | run: |
supersetbot docker \ supersetbot docker \
--push \
--load \
--preset ci \ --preset ci \
--platform linux/amd64 \ --platform linux/amd64 \
--context-ref "$RELEASE" \ --context-ref "$RELEASE" \
@@ -190,7 +194,7 @@ jobs:
needs: [ephemeral-env-comment, ephemeral-docker-build] needs: [ephemeral-env-comment, ephemeral-docker-build]
if: needs.ephemeral-env-comment.outputs.slash-command == 'up' if: needs.ephemeral-env-comment.outputs.slash-command == 'up'
name: Spin up an ephemeral environment name: Spin up an ephemeral environment
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
+2 -2
View File
@@ -8,7 +8,7 @@ on:
jobs: jobs:
config: config:
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
outputs: outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }} has-secrets: ${{ steps.check.outputs.has-secrets }}
steps: steps:
@@ -24,7 +24,7 @@ jobs:
needs: config needs: config
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
name: Generate Report name: Generate Report
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -11,7 +11,7 @@ on:
jobs: jobs:
validate-all-ghas: validate-all-ghas:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
+1 -1
View File
@@ -9,7 +9,7 @@ on:
jobs: jobs:
superbot-orglabel: superbot-orglabel:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
+1 -1
View File
@@ -7,7 +7,7 @@ jobs:
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/labeler@v5 - uses: actions/labeler@v5
with: with:
+1 -1
View File
@@ -6,7 +6,7 @@ on:
jobs: jobs:
latest-release: latest-release:
name: Add/update tag to new release name: Add/update tag to new release
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: write contents: write
+1 -1
View File
@@ -12,7 +12,7 @@ concurrency:
jobs: jobs:
license_check: license_check:
name: License Check name: License Check
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4 uses: actions/checkout@v4
+1 -1
View File
@@ -11,7 +11,7 @@ concurrency:
jobs: jobs:
check-hold-label: check-hold-label:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: Check for 'hold' label - name: Check for 'hold' label
uses: actions/github-script@v7 uses: actions/github-script@v7
+1 -1
View File
@@ -10,7 +10,7 @@ on:
jobs: jobs:
lint-check: lint-check:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
+1 -1
View File
@@ -15,7 +15,7 @@ concurrency:
jobs: jobs:
pre-commit: pre-commit:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
python-version: ["current", "next", "previous"] python-version: ["current", "next", "previous"]
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
prefer_typescript: prefer_typescript:
if: github.ref == 'ref/heads/master' && github.event_name == 'pull_request' if: github.ref == 'ref/heads/master' && github.event_name == 'pull_request'
name: Prefer TypeScript name: Prefer TypeScript
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
+2 -2
View File
@@ -8,7 +8,7 @@ on:
jobs: jobs:
config: config:
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
outputs: outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }} has-secrets: ${{ steps.check.outputs.has-secrets }}
steps: steps:
@@ -25,7 +25,7 @@ jobs:
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
name: Bump version and publish package(s) name: Bump version and publish package(s)
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
@@ -6,7 +6,7 @@ on:
jobs: jobs:
config: config:
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
outputs: outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }} has-secrets: ${{ steps.check.outputs.has-secrets }}
steps: steps:
@@ -21,7 +21,7 @@ jobs:
cypress-applitools: cypress-applitools:
needs: config needs: config
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -12,7 +12,7 @@ env:
jobs: jobs:
config: config:
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
outputs: outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }} has-secrets: ${{ steps.check.outputs.has-secrets }}
steps: steps:
@@ -27,7 +27,7 @@ jobs:
cron: cron:
needs: config needs: config
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
node: [20] node: [20]
+1 -1
View File
@@ -15,7 +15,7 @@ concurrency:
jobs: jobs:
test-load-examples: test-load-examples:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
env: env:
PYTHONPATH: ${{ github.workspace }} PYTHONPATH: ${{ github.workspace }}
SUPERSET_CONFIG: tests.integration_tests.superset_test_config SUPERSET_CONFIG: tests.integration_tests.superset_test_config
+2 -2
View File
@@ -12,7 +12,7 @@ on:
jobs: jobs:
config: config:
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
outputs: outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }} has-secrets: ${{ steps.check.outputs.has-secrets }}
steps: steps:
@@ -28,7 +28,7 @@ jobs:
needs: config needs: config
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
name: Build & Deploy name: Build & Deploy
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4 uses: actions/checkout@v4
+1 -1
View File
@@ -51,7 +51,7 @@ jobs:
https://www.plaidcloud.com/ https://www.plaidcloud.com/
build-deploy: build-deploy:
name: Build & Deploy name: Build & Deploy
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
defaults: defaults:
run: run:
working-directory: docs working-directory: docs
-1
View File
@@ -28,7 +28,6 @@ concurrency:
jobs: jobs:
cypress-matrix: cypress-matrix:
# Somehow one test flakes on 24.04 for unknown reasons, this is the only GHA left on 22.04
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: read contents: read
+1 -1
View File
@@ -15,7 +15,7 @@ concurrency:
jobs: jobs:
frontend-build: frontend-build:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4 uses: actions/checkout@v4
+1 -1
View File
@@ -13,7 +13,7 @@ concurrency:
jobs: jobs:
lint-test: lint-test:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4 uses: actions/checkout@v4
+1 -1
View File
@@ -20,7 +20,7 @@ on:
jobs: jobs:
release: release:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: write contents: write
pull-requests: write pull-requests: write
@@ -15,7 +15,7 @@ concurrency:
jobs: jobs:
test-mysql: test-mysql:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
env: env:
PYTHONPATH: ${{ github.workspace }} PYTHONPATH: ${{ github.workspace }}
SUPERSET_CONFIG: tests.integration_tests.superset_test_config SUPERSET_CONFIG: tests.integration_tests.superset_test_config
@@ -74,7 +74,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}
verbose: true verbose: true
test-postgres: test-postgres:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
python-version: ["current", "next", "previous"] python-version: ["current", "next", "previous"]
@@ -136,7 +136,7 @@ jobs:
verbose: true verbose: true
test-sqlite: test-sqlite:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
env: env:
PYTHONPATH: ${{ github.workspace }} PYTHONPATH: ${{ github.workspace }}
SUPERSET_CONFIG: tests.integration_tests.superset_test_config SUPERSET_CONFIG: tests.integration_tests.superset_test_config
@@ -16,7 +16,7 @@ concurrency:
jobs: jobs:
test-postgres-presto: test-postgres-presto:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
env: env:
PYTHONPATH: ${{ github.workspace }} PYTHONPATH: ${{ github.workspace }}
SUPERSET_CONFIG: tests.integration_tests.superset_test_config SUPERSET_CONFIG: tests.integration_tests.superset_test_config
@@ -84,7 +84,7 @@ jobs:
verbose: true verbose: true
test-postgres-hive: test-postgres-hive:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
env: env:
PYTHONPATH: ${{ github.workspace }} PYTHONPATH: ${{ github.workspace }}
SUPERSET_CONFIG: tests.integration_tests.superset_test_config SUPERSET_CONFIG: tests.integration_tests.superset_test_config
@@ -16,7 +16,7 @@ concurrency:
jobs: jobs:
unit-tests: unit-tests:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
python-version: ["current", "next"] python-version: ["current", "next"]
+2 -2
View File
@@ -15,7 +15,7 @@ concurrency:
jobs: jobs:
frontend-check-translations: frontend-check-translations:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -46,7 +46,7 @@ jobs:
npm run build-translation npm run build-translation
babel-extract: babel-extract:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4 uses: actions/checkout@v4
+1 -1
View File
@@ -18,7 +18,7 @@ concurrency:
jobs: jobs:
app-checks: app-checks:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
steps: steps:
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4 uses: actions/checkout@v4
+1 -1
View File
@@ -15,7 +15,7 @@ on:
jobs: jobs:
supersetbot: supersetbot:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
if: > if: >
github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@supersetbot')) (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@supersetbot'))
+15 -12
View File
@@ -23,7 +23,7 @@ on:
- 'false' - 'false'
jobs: jobs:
config: config:
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
outputs: outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }} has-secrets: ${{ steps.check.outputs.has-secrets }}
steps: steps:
@@ -39,26 +39,23 @@ jobs:
needs: config needs: config
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
name: docker-release name: docker-release
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
build_preset: ["dev", "lean", "py310", "websocket", "dockerize", "py311"] build_preset: ["dev", "lean", "py310", "websocket", "dockerize", "py311"]
fail-fast: false fail-fast: false
steps: steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Docker Environment
uses: ./.github/actions/setup-docker
with:
dockerhub-user: ${{ secrets.DOCKERHUB_USER }}
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
install-docker-compose: "false"
build: "true"
- name: Use Node.js 20 - name: Use Node.js 20
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
@@ -67,6 +64,13 @@ jobs:
- name: Setup supersetbot - name: Setup supersetbot
uses: ./.github/actions/setup-supersetbot/ uses: ./.github/actions/setup-supersetbot/
- name: Try to login to DockerHub
continue-on-error: true
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Execute custom Node.js script - name: Execute custom Node.js script
env: env:
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
@@ -87,7 +91,6 @@ jobs:
fi fi
supersetbot docker \ supersetbot docker \
--push \
--preset ${{ matrix.build_preset }} \ --preset ${{ matrix.build_preset }} \
--context "$EVENT" \ --context "$EVENT" \
--context-ref "$RELEASE" $FORCE_LATEST \ --context-ref "$RELEASE" $FORCE_LATEST \
@@ -100,7 +103,7 @@ jobs:
update-prs-with-release-info: update-prs-with-release-info:
needs: config needs: config
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
+2 -2
View File
@@ -8,7 +8,7 @@ on:
jobs: jobs:
config: config:
runs-on: ubuntu-24.04 runs-on: "ubuntu-22.04"
outputs: outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }} has-secrets: ${{ steps.check.outputs.has-secrets }}
steps: steps:
@@ -23,7 +23,7 @@ jobs:
process-and-upload: process-and-upload:
needs: config needs: config
if: needs.config.outputs.has-secrets if: needs.config.outputs.has-secrets
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
name: Generate Reports name: Generate Reports
steps: steps:
- name: Checkout Repository - name: Checkout Repository
+1 -1
View File
@@ -6,7 +6,7 @@ on:
jobs: jobs:
welcome: welcome:
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
permissions: permissions:
pull-requests: write pull-requests: write
+4
View File
@@ -38,6 +38,10 @@ repos:
types-paramiko, types-paramiko,
types-Markdown, types-Markdown,
] ]
- repo: https://github.com/peterdemin/pip-compile-multi
rev: v2.6.4
hooks:
- id: pip-compile-multi-verify
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0 rev: v5.0.0
hooks: hooks:
+22 -39
View File
@@ -52,11 +52,12 @@ WORKDIR /app/superset-frontend
RUN mkdir -p /app/superset/static/assets \ RUN mkdir -p /app/superset/static/assets \
/app/superset/translations /app/superset/translations
# Copy translation files
COPY superset/translations /app/superset/translations
# Mount package files and install dependencies if not in dev mode # Mount package files and install dependencies if not in dev mode
RUN --mount=type=bind,source=./superset-frontend/package.json,target=./package.json \ RUN --mount=type=bind,source=./superset-frontend/package.json,target=./package.json \
--mount=type=bind,source=./superset-frontend/package-lock.json,target=./package-lock.json \ --mount=type=bind,source=./superset-frontend/package-lock.json,target=./package-lock.json \
--mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/root/.npm \
if [ "$DEV_MODE" = "false" ]; then \ if [ "$DEV_MODE" = "false" ]; then \
npm ci; \ npm ci; \
else \ else \
@@ -67,24 +68,16 @@ RUN --mount=type=bind,source=./superset-frontend/package.json,target=./package.j
COPY superset-frontend /app/superset-frontend COPY superset-frontend /app/superset-frontend
# Build the frontend if not in dev mode # Build the frontend if not in dev mode
RUN --mount=type=cache,target=/app/superset-frontend/.temp_cache \ RUN if [ "$DEV_MODE" = "false" ]; then \
--mount=type=cache,target=/root/.npm \
if [ "$DEV_MODE" = "false" ]; then \
echo "Running 'npm run ${BUILD_CMD}'"; \ echo "Running 'npm run ${BUILD_CMD}'"; \
if [ "$BUILD_TRANSLATIONS" = "true" ]; then \
npm run build-translation; \
fi; \
npm run ${BUILD_CMD}; \ npm run ${BUILD_CMD}; \
else \ else \
echo "Skipping 'npm run ${BUILD_CMD}' in dev mode"; \ echo "Skipping 'npm run ${BUILD_CMD}' in dev mode"; \
fi; fi && \
rm -rf /app/superset/translations/*/*/*.po
# Copy translation files
COPY superset/translations /app/superset/translations
# Build the frontend if not in dev mode
RUN if [ "$BUILD_TRANSLATIONS" = "true" ]; then \
npm run build-translation; \
fi; \
rm -rf /app/superset/translations/*/*/*.po; \
rm -rf /app/superset/translations/*/*/*.mo;
###################################################################### ######################################################################
@@ -110,7 +103,7 @@ RUN useradd --user-group -d ${SUPERSET_HOME} -m --no-log-init --shell /bin/bash
# Some bash scripts needed throughout the layers # Some bash scripts needed throughout the layers
COPY --chmod=755 docker/*.sh /app/docker/ COPY --chmod=755 docker/*.sh /app/docker/
RUN pip install --no-cache-dir --upgrade uv RUN pip install --no-cache-dir --upgrade setuptools pip uv
# Using uv as it's faster/simpler than pip # Using uv as it's faster/simpler than pip
RUN uv venv /app/.venv RUN uv venv /app/.venv
@@ -119,9 +112,9 @@ ENV PATH="/app/.venv/bin:${PATH}"
# Install Playwright and optionally setup headless browsers # Install Playwright and optionally setup headless browsers
ARG INCLUDE_CHROMIUM="true" ARG INCLUDE_CHROMIUM="true"
ARG INCLUDE_FIREFOX="false" ARG INCLUDE_FIREFOX="false"
RUN --mount=type=cache,target=/root/.cache/uv\ RUN --mount=type=cache,target=/root/.cache/pip \
if [ "$INCLUDE_CHROMIUM" = "true" ] || [ "$INCLUDE_FIREFOX" = "true" ]; then \ if [ "$INCLUDE_CHROMIUM" = "true" ] || [ "$INCLUDE_FIREFOX" = "true" ]; then \
uv pip install playwright && \ pip install playwright && \
playwright install-deps && \ playwright install-deps && \
if [ "$INCLUDE_CHROMIUM" = "true" ]; then playwright install chromium; fi && \ if [ "$INCLUDE_CHROMIUM" = "true" ]; then playwright install chromium; fi && \
if [ "$INCLUDE_FIREFOX" = "true" ]; then playwright install firefox; fi; \ if [ "$INCLUDE_FIREFOX" = "true" ]; then playwright install firefox; fi; \
@@ -136,15 +129,12 @@ FROM python-base AS python-translation-compiler
# Install Python dependencies using docker/pip-install.sh # Install Python dependencies using docker/pip-install.sh
COPY requirements/translations.txt requirements/ COPY requirements/translations.txt requirements/
RUN --mount=type=cache,target=/root/.cache/uv \ RUN --mount=type=cache,target=/root/.cache/pip \
/app/docker/pip-install.sh --requires-build-essential -r requirements/translations.txt /app/docker/pip-install.sh -r requirements/translations.txt
COPY superset/translations/ /app/translations_mo/ COPY superset/translations/ /app/translations_mo/
RUN if [ "$BUILD_TRANSLATIONS" = "true" ]; then \ RUN pybabel compile -d /app/translations_mo | true && \
pybabel compile -d /app/translations_mo | true; \ rm -f /app/translations_mo/*/*/*.po
fi; \
rm -f /app/translations_mo/*/*/*.po; \
rm -f /app/translations_mo/*/*/*.json;
###################################################################### ######################################################################
# Python APP common layer # Python APP common layer
@@ -185,11 +175,6 @@ RUN /app/docker/apt-install.sh \
# Copy compiled things from previous stages # Copy compiled things from previous stages
COPY --from=superset-node /app/superset/static/assets superset/static/assets COPY --from=superset-node /app/superset/static/assets superset/static/assets
# TODO, when the next version comes out, use --exclude superset/translations
COPY superset superset
# TODO in the meantime, remove the .po files
RUN rm superset/translations/*/*/*.po
# Merging translations from backend and frontend stages # Merging translations from backend and frontend stages
COPY --from=superset-node /app/superset/translations superset/translations COPY --from=superset-node /app/superset/translations superset/translations
COPY --from=python-translation-compiler /app/translations_mo superset/translations COPY --from=python-translation-compiler /app/translations_mo superset/translations
@@ -202,13 +187,12 @@ EXPOSE ${SUPERSET_PORT}
# Final lean image... # Final lean image...
###################################################################### ######################################################################
FROM python-common AS lean FROM python-common AS lean
COPY superset superset
# Install Python dependencies using docker/pip-install.sh # Install Python dependencies using docker/pip-install.sh
COPY requirements/base.txt requirements/ COPY requirements/base.txt requirements/
RUN --mount=type=cache,target=/root/.cache/uv \ RUN --mount=type=cache,target=/root/.cache/pip \
/app/docker/pip-install.sh --requires-build-essential -r requirements/base.txt /app/docker/pip-install.sh --requires-build-essential -r requirements/base.txt && \
# Install the superset package
RUN --mount=type=cache,target=/root/.cache/uv \
uv pip install . uv pip install .
RUN python -m compileall /app/superset RUN python -m compileall /app/superset
@@ -219,6 +203,7 @@ USER superset
# Dev image... # Dev image...
###################################################################### ######################################################################
FROM python-common AS dev FROM python-common AS dev
COPY superset superset
# Debian libs needed for dev # Debian libs needed for dev
RUN /app/docker/apt-install.sh \ RUN /app/docker/apt-install.sh \
@@ -229,10 +214,8 @@ RUN /app/docker/apt-install.sh \
# Copy development requirements and install them # Copy development requirements and install them
COPY requirements/*.txt requirements/ COPY requirements/*.txt requirements/
# Install Python dependencies using docker/pip-install.sh # Install Python dependencies using docker/pip-install.sh
RUN --mount=type=cache,target=/root/.cache/uv \ RUN --mount=type=cache,target=/root/.cache/pip \
/app/docker/pip-install.sh --requires-build-essential -r requirements/development.txt /app/docker/pip-install.sh --requires-build-essential -r requirements/development.txt && \
# Install the superset package
RUN --mount=type=cache,target=/root/.cache/uv \
uv pip install . uv pip install .
RUN python -m compileall /app/superset RUN python -m compileall /app/superset
+3 -3
View File
@@ -272,14 +272,14 @@ class GitLogs:
@staticmethod @staticmethod
def _git_get_current_head() -> str: def _git_get_current_head() -> str:
output = os.popen("git status | head -1").read() # noqa: S605, S607 output = os.popen("git status | head -1").read()
match = re.match("(?:HEAD detached at|On branch) (.*)", output) match = re.match("(?:HEAD detached at|On branch) (.*)", output)
if not match: if not match:
return "" return ""
return match.group(1) return match.group(1)
def _git_checkout(self, git_ref: str) -> None: def _git_checkout(self, git_ref: str) -> None:
os.popen(f"git checkout {git_ref}").read() # noqa: S605 os.popen(f"git checkout {git_ref}").read()
current_head = self._git_get_current_head() current_head = self._git_get_current_head()
if current_head != git_ref: if current_head != git_ref:
print(f"Could not checkout {git_ref}") print(f"Could not checkout {git_ref}")
@@ -290,7 +290,7 @@ class GitLogs:
current_git_ref = self._git_get_current_head() current_git_ref = self._git_get_current_head()
self._git_checkout(self._git_ref) self._git_checkout(self._git_ref)
output = ( output = (
os.popen('git --no-pager log --pretty=format:"%h|%an|%ae|%ad|%s|"') # noqa: S605, S607 os.popen('git --no-pager log --pretty=format:"%h|%an|%ae|%ad|%s|"')
.read() .read()
.split("\n") .split("\n")
) )
+1 -1
View File
@@ -31,7 +31,7 @@ except ModuleNotFoundError:
RECEIVER_EMAIL = "dev@superset.apache.org" RECEIVER_EMAIL = "dev@superset.apache.org"
PROJECT_NAME = "Superset" PROJECT_NAME = "Superset"
PROJECT_MODULE = "superset" PROJECT_MODULE = "superset"
PROJECT_DESCRIPTION = "Apache Superset is a modern, enterprise-ready business intelligence web application." # noqa: E501 PROJECT_DESCRIPTION = "Apache Superset is a modern, enterprise-ready business intelligence web application."
def string_comma_to_list(message: str) -> list[str]: def string_comma_to_list(message: str) -> list[str]:
+7 -8
View File
@@ -23,12 +23,12 @@ from typing import Optional
import requests import requests
# Part 1: Verify SHA512 hash - this is the same as running `shasum -a 512 {release}` and comparing it against `{release}.sha512` # noqa: E501 # Part 1: Verify SHA512 hash - this is the same as running `shasum -a 512 {release}` and comparing it against `{release}.sha512`
def get_sha512_hash(filename: str) -> str: def get_sha512_hash(filename: str) -> str:
"""Run the shasum command on the file and return the SHA512 hash.""" """Run the shasum command on the file and return the SHA512 hash."""
result = subprocess.run(["shasum", "-a", "512", filename], stdout=subprocess.PIPE) # noqa: S603, S607 result = subprocess.run(["shasum", "-a", "512", filename], stdout=subprocess.PIPE)
sha512_hash = result.stdout.decode().split()[0] sha512_hash = result.stdout.decode().split()[0]
return sha512_hash return sha512_hash
@@ -43,7 +43,7 @@ def read_sha512_file(filename: str) -> str:
def verify_sha512(filename: str) -> str: def verify_sha512(filename: str) -> str:
"""Verify if the SHA512 hash of the file matches with the hash in the .sha512 file.""" # noqa: E501 """Verify if the SHA512 hash of the file matches with the hash in the .sha512 file."""
sha512_hash = get_sha512_hash(filename) sha512_hash = get_sha512_hash(filename)
sha512_file_content = read_sha512_file(filename) sha512_file_content = read_sha512_file(filename)
@@ -53,15 +53,14 @@ def verify_sha512(filename: str) -> str:
return "SHA failed" return "SHA failed"
# Part 2: Verify RSA key - this is the same as running `gpg --verify {release}.asc {release}` and comparing the RSA key and email address against the KEYS file # noqa: E501 # Part 2: Verify RSA key - this is the same as running `gpg --verify {release}.asc {release}` and comparing the RSA key and email address against the KEYS file
def get_gpg_info(filename: str) -> tuple[Optional[str], Optional[str]]: def get_gpg_info(filename: str) -> tuple[Optional[str], Optional[str]]:
"""Run the GPG verify command and extract RSA key and email address.""" """Run the GPG verify command and extract RSA key and email address."""
asc_filename = filename + ".asc" asc_filename = filename + ".asc"
result = subprocess.run( # noqa: S603 result = subprocess.run(
["gpg", "--verify", asc_filename, filename], # noqa: S607 ["gpg", "--verify", asc_filename, filename], capture_output=True
capture_output=True, # noqa: S607
) )
output = result.stderr.decode() output = result.stderr.decode()
@@ -91,7 +90,7 @@ def get_gpg_info(filename: str) -> tuple[Optional[str], Optional[str]]:
def verify_key(key: str, email: Optional[str]) -> str: def verify_key(key: str, email: Optional[str]) -> str:
"""Fetch the KEYS file and verify if the RSA/EDDSA key and email match.""" """Fetch the KEYS file and verify if the RSA/EDDSA key and email match."""
url = "https://downloads.apache.org/superset/KEYS" url = "https://downloads.apache.org/superset/KEYS"
response = requests.get(url) # noqa: S113 response = requests.get(url)
if response.status_code == 200: if response.status_code == 200:
if key not in response.text: if key not in response.text:
return "RSA/EDDSA key not found on KEYS page" return "RSA/EDDSA key not found on KEYS page"
+1 -1
View File
@@ -79,7 +79,7 @@ Join our growing community!
- [Astronomer](https://www.astronomer.io) [@ryw] - [Astronomer](https://www.astronomer.io) [@ryw]
- [Avesta Technologies](https://avestatechnologies.com/) [@TheRum] - [Avesta Technologies](https://avestatechnologies.com/) [@TheRum]
- [Caizin](https://caizin.com/) [@tejaskatariya] - [Caizin](https://caizin.com/) [@tejaskatariya]
- [Careem](https://www.careem.com/) [@samraHanif0340] - [Careem](https://www.careem.com/) [@SamraHanifCareem]
- [Cloudsmith](https://cloudsmith.io) [@alancarson] - [Cloudsmith](https://cloudsmith.io) [@alancarson]
- [Cyberhaven](https://www.cyberhaven.com/) [@toliver-ch] - [Cyberhaven](https://www.cyberhaven.com/) [@toliver-ch]
- [Deepomatic](https://deepomatic.com/) [@Zanoellia] - [Deepomatic](https://deepomatic.com/) [@Zanoellia]
+1 -5
View File
@@ -35,14 +35,11 @@ x-superset-volumes: &superset-volumes
x-common-build: &common-build x-common-build: &common-build
context: . context: .
target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean` target: dev
cache_from: cache_from:
- apache/superset-cache:3.10-slim-bookworm - apache/superset-cache:3.10-slim-bookworm
args: args:
DEV_MODE: "true" DEV_MODE: "true"
INCLUDE_CHROMIUM: ${INCLUDE_CHROMIUM:-false}
INCLUDE_FIREFOX: ${INCLUDE_FIREFOX:-false}
BUILD_TRANSLATIONS: ${BUILD_TRANSLATIONS:-false}
services: services:
nginx: nginx:
@@ -160,7 +157,6 @@ services:
# and build it on startup while firing docker-frontend.sh in dev mode, where # and build it on startup while firing docker-frontend.sh in dev mode, where
# it'll mount and watch local files and rebuild as you update them # it'll mount and watch local files and rebuild as you update them
DEV_MODE: "true" DEV_MODE: "true"
BUILD_TRANSLATIONS: ${BUILD_TRANSLATIONS:-false}
environment: environment:
# set this to false if you have perf issues running the npm i; npm run dev in-docker # set this to false if you have perf issues running the npm i; npm run dev in-docker
# if you do so, you have to run this manually on the host, which should perform better! # if you do so, you have to run this manually on the host, which should perform better!
+3 -8
View File
@@ -20,7 +20,8 @@ set -eo pipefail
# Make python interactive # Make python interactive
if [ "$DEV_MODE" == "true" ]; then if [ "$DEV_MODE" == "true" ]; then
echo "Reinstalling the app in editable mode" echo "[DEV_MODE detected] Setting the superset package to be in editable mode"
echo "RUN: uv pip install -e ."
uv pip install -e . uv pip install -e .
fi fi
REQUIREMENTS_LOCAL="/app/docker/requirements-local.txt" REQUIREMENTS_LOCAL="/app/docker/requirements-local.txt"
@@ -30,18 +31,12 @@ if [ "$CYPRESS_CONFIG" == "true" ]; then
export SUPERSET_TESTENV=true export SUPERSET_TESTENV=true
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset
fi fi
if [[ "$DATABASE_DIALECT" == postgres* ]] ; then
echo "Installing postgres requirements"
uv pip install -e .[postgres]
fi
# #
# Make sure we have dev requirements installed # Make sure we have dev requirements installed
# #
if [ -f "${REQUIREMENTS_LOCAL}" ]; then if [ -f "${REQUIREMENTS_LOCAL}" ]; then
echo "Installing local overrides at ${REQUIREMENTS_LOCAL}" echo "Installing python packages specified at ${REQUIREMENTS_LOCAL}"
uv pip install --no-cache-dir -r "${REQUIREMENTS_LOCAL}" uv pip install --no-cache-dir -r "${REQUIREMENTS_LOCAL}"
else
echo "Skipping local overrides"
fi fi
case "${1}" in case "${1}" in
+1 -1
View File
@@ -35,7 +35,7 @@ if [ "$BUILD_SUPERSET_FRONTEND_IN_DOCKER" = "true" ]; then
echo "Running `npm install`" echo "Running `npm install`"
npm install npm install
echo "Start webpack dev server" echo "Running frontend"
npm run dev npm run dev
else else
+1 -11
View File
@@ -30,15 +30,9 @@ fi
echo_step() { echo_step() {
cat <<EOF cat <<EOF
###################################################################### ######################################################################
Docker Init Step ${1}/${STEP_CNT} [${2}] -- ${3}
Init Step ${1}/${STEP_CNT} [${2}] -- ${3}
###################################################################### ######################################################################
EOF EOF
} }
ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin}" ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin}"
@@ -52,7 +46,6 @@ fi
# Initialize the database # Initialize the database
echo_step "1" "Starting" "Applying DB migrations" echo_step "1" "Starting" "Applying DB migrations"
superset db upgrade superset db upgrade
echo_step "1" "Complete" "Applying DB migrations"
# Create an admin user # Create an admin user
echo_step "2" "Starting" "Setting up admin user ( admin / $ADMIN_PASSWORD )" echo_step "2" "Starting" "Setting up admin user ( admin / $ADMIN_PASSWORD )"
@@ -62,11 +55,9 @@ superset fab create-admin \
--lastname Admin \ --lastname Admin \
--email admin@superset.com \ --email admin@superset.com \
--password "$ADMIN_PASSWORD" --password "$ADMIN_PASSWORD"
echo_step "2" "Complete" "Setting up admin user"
# Create default roles and permissions # Create default roles and permissions
echo_step "3" "Starting" "Setting up roles and perms" echo_step "3" "Starting" "Setting up roles and perms"
superset init superset init
echo_step "3" "Complete" "Setting up roles and perms"
if [ "$SUPERSET_LOAD_EXAMPLES" = "yes" ]; then if [ "$SUPERSET_LOAD_EXAMPLES" = "yes" ]; then
# Load some data to play with # Load some data to play with
@@ -78,5 +69,4 @@ if [ "$SUPERSET_LOAD_EXAMPLES" = "yes" ]; then
else else
superset load_examples --force superset load_examples --force
fi fi
echo_step "4" "Complete" "Loading examples"
fi fi
+2 -1
View File
@@ -99,10 +99,11 @@ CELERY_CONFIG = CeleryConfig
FEATURE_FLAGS = {"ALERT_REPORTS": True} FEATURE_FLAGS = {"ALERT_REPORTS": True}
ALERT_REPORTS_NOTIFICATION_DRY_RUN = True ALERT_REPORTS_NOTIFICATION_DRY_RUN = True
WEBDRIVER_BASEURL = "http://superset:8088/" # When using docker compose baseurl should be http://superset_app:8088/ # noqa: E501 WEBDRIVER_BASEURL = "http://superset:8088/" # When using docker compose baseurl should be http://superset_app:8088/
# The base URL for the email report hyperlinks. # The base URL for the email report hyperlinks.
WEBDRIVER_BASEURL_USER_FRIENDLY = WEBDRIVER_BASEURL WEBDRIVER_BASEURL_USER_FRIENDLY = WEBDRIVER_BASEURL
SQLLAB_CTAS_NO_LIMIT = True SQLLAB_CTAS_NO_LIMIT = True
LOG_LEVEL = logging.INFO
# #
# Optionally import superset_config_docker.py (which will have been included on # Optionally import superset_config_docker.py (which will have been included on
-1
View File
@@ -63,7 +63,6 @@
"Fiji", "Fiji",
"Finland", "Finland",
"France", "France",
"France (with overseas)",
"France (regions)", "France (regions)",
"French Polynesia", "French Polynesia",
"Gabon", "Gabon",
+5 -18
View File
@@ -72,19 +72,6 @@ documentation.
configured to be secure. configured to be secure.
::: :::
### Supported environment variables
Affecting the Docker build process:
- **SUPERSET_BUILD_TARGET (default=dev):** which --target to build, either `lean` or `dev` are commonly used
- **INCLUDE_FIREFOX (default=false):** whether to include the Firefox headless browser in the build
- **INCLUDE_CHROMIUM (default=false):** whether to include the Firefox headless browser in the build
- **BUILD_TRANSLATIONS(default=false):** whether to compile the translations from the .po files available
For more env vars that affect your configuration, see this
[superset_config.py](https://github.com/apache/superset/blob/master/docker/pythonpath_dev/superset_config.py)
used in the `docker compose` context to assign env vars to the superset configuration.
### Nuking the postgres database ### Nuking the postgres database
At times, it's possible to end up with your development database in a bad state, it's At times, it's possible to end up with your development database in a bad state, it's
@@ -255,19 +242,19 @@ If you add a new requirement or update an existing requirement (per the `install
$ python3 -m venv venv $ python3 -m venv venv
$ source venv/bin/activate $ source venv/bin/activate
$ python3 -m pip install -r requirements/development.txt $ python3 -m pip install -r requirements/development.txt
$ ./scripts/uv-pip-compile.sh $ pip-compile-multi --no-upgrade
``` ```
When upgrading the version number of a single package, you should run `./scripts/uv-pip-compile.sh` with the `-P` flag: When upgrading the version number of a single package, you should run `pip-compile-multi` with the `-P` flag:
```bash ```bash
$ ./scripts/uv-pip-compile.sh -P some-package-to-upgrade $ pip-compile-multi -P my-package
``` ```
To bring all dependencies up to date as per the restrictions defined in `setup.py` and `requirements/*.in`, run `./scripts/uv-pip-compile.sh --upgrade` To bring all dependencies up to date as per the restrictions defined in `setup.py` and `requirements/*.in`, run pip-compile-multi` without any flags:
```bash ```bash
$ ./scripts/uv-pip-compile.sh --upgrade $ pip-compile-multi
``` ```
This should be done periodically, but it is recommended to do thorough manual testing of the application to ensure no breaking changes have been introduced that aren't caught by the unit and integration tests. This should be done periodically, but it is recommended to do thorough manual testing of the application to ensure no breaking changes have been introduced that aren't caught by the unit and integration tests.
+18 -52
View File
@@ -24,7 +24,7 @@ name = "apache-superset"
description = "A modern, enterprise-ready business intelligence web application" description = "A modern, enterprise-ready business intelligence web application"
readme = "README.md" readme = "README.md"
dynamic = ["version", "scripts", "entry-points"] dynamic = ["version", "scripts", "entry-points"]
requires-python = ">=3.9" requires-python = "~=3.9"
license = { file="LICENSE.txt" } license = { file="LICENSE.txt" }
authors = [ authors = [
{ name = "Apache Software Foundation", email = "dev@superset.apache.org" }, { name = "Apache Software Foundation", email = "dev@superset.apache.org" },
@@ -191,6 +191,7 @@ development = [
"grpcio>=1.55.3", "grpcio>=1.55.3",
"openapi-spec-validator", "openapi-spec-validator",
"parameterized", "parameterized",
"pip-compile-multi",
"pre-commit", "pre-commit",
"progress>=1.5,<2", "progress>=1.5,<2",
"psutil", "psutil",
@@ -215,7 +216,7 @@ combine_as_imports = true
include_trailing_comma = true include_trailing_comma = true
line_length = 88 line_length = 88
known_first_party = "superset" known_first_party = "superset"
known_third_party = "alembic, apispec, backoff, celery, click, colorama, cron_descriptor, croniter, cryptography, dateutil, deprecation, flask, flask_appbuilder, flask_babel, flask_caching, flask_compress, flask_jwt_extended, flask_login, flask_migrate, flask_sqlalchemy, flask_talisman, flask_testing, flask_wtf, freezegun, geohash, geopy, holidays, humanize, isodate, jinja2, jwt, markdown, markupsafe, marshmallow, msgpack, nh3, numpy, pandas, parameterized, parsedatetime, pgsanity, polyline, prison, progress, pyarrow, sqlalchemy_bigquery, pyhive, pyparsing, pytest, pytest_mock, pytz, redis, requests, selenium, setuptools, shillelagh, simplejson, slack, sqlalchemy, sqlalchemy_utils, sqlparse, typing_extensions, urllib3, werkzeug, wtforms, wtforms_json, yaml" known_third_party = "alembic, apispec, backoff, celery, click, colorama, cron_descriptor, croniter, cryptography, dateutil, deprecation, flask, flask_appbuilder, flask_babel, flask_caching, flask_compress, flask_jwt_extended, flask_login, flask_migrate, flask_sqlalchemy, flask_talisman, flask_testing, flask_wtf, freezegun, geohash, geopy, holidays, humanize, isodate, jinja2, jwt, markdown, markupsafe, marshmallow, msgpack, nh3, numpy, pandas, parameterized, parsedatetime, pgsanity, pkg_resources, polyline, prison, progress, pyarrow, sqlalchemy_bigquery, pyhive, pyparsing, pytest, pytest_mock, pytz, redis, requests, selenium, setuptools, shillelagh, simplejson, slack, sqlalchemy, sqlalchemy_utils, sqlparse, typing_extensions, urllib3, werkzeug, wtforms, wtforms_json, yaml"
multi_line_output = 3 multi_line_output = 3
order_by_type = false order_by_type = false
@@ -276,8 +277,8 @@ exclude = [
line-length = 88 line-length = 88
indent-width = 4 indent-width = 4
# Assume Python 3.9 # Assume Python 3.8
target-version = "py39" target-version = "py310"
[tool.ruff.lint] [tool.ruff.lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
@@ -290,24 +291,22 @@ select = [
"E9", "E9",
"PT009", "PT009",
"TRY201", "TRY201",
"B", # TODO add these rules in follow up PR
"C", # "B",
"E", # "C",
"F", # "E",
"F", # "F",
"I", #"F",
"N", # "I",
"PT", # "N",
"Q", # "PT",
"S", # "Q",
"T", # "S",
"W", # "T",
#"W",
] ]
ignore = [ ignore = [
"S101", "S101",
"PT006",
"T201",
"N999",
] ]
extend-select = ["I"] extend-select = ["I"]
@@ -361,36 +360,3 @@ docstring-code-format = false
# This only has an effect when the `docstring-code-format` setting is # This only has an effect when the `docstring-code-format` setting is
# enabled. # enabled.
docstring-code-line-length = "dynamic" docstring-code-line-length = "dynamic"
[tool.liccheck]
requirement_txt_file = "requirements/base.txt"
authorized_licenses = [
"academic free license (afl)",
"apache license 2.0",
"apache software",
"apache software, bsd",
"bsd",
"isc license (iscl)",
"isc license",
"mit",
"mozilla public license 2.0 (mpl 2.0)",
"osi approved",
"osi approved",
"python software foundation",
"the unlicense (unlicense)",
"the unlicense",
]
[tool.liccheck.authorized_packages]
# --------------------------------------------------------------
# These are ok, checked manually
# Seems ok, might need legal review
# https://github.com/urschrei/pypolyline/blob/master/LICENSE.md
polyline = "2"
# Apache 2.0 https://github.com/hkwi/python-geohash
python-geohash = "0"
# --------------------------------------------------------------
# TODO REMOVE THESE DEPS FROM CODEBASE
func-timeout = "4" # AGPL
paramiko = "3" # GPL
pyxlsb = "1" # GPL
+1
View File
@@ -16,6 +16,7 @@
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
-e file:.
urllib3>=1.26.18 urllib3>=1.26.18
werkzeug>=3.0.1 werkzeug>=3.0.1
numexpr>=2.9.0 numexpr>=2.9.0
+75 -68
View File
@@ -1,10 +1,17 @@
# This file was autogenerated by uv via the following command: # SHA1:04f7e0860829f18926ea238354e6d4a6ab823d50
# uv pip compile pyproject.toml requirements/base.in -o requirements/base.txt #
# This file is autogenerated by pip-compile-multi
# To update, run:
#
# pip-compile-multi
#
-e file:.
# via -r requirements/base.in
alembic==1.14.0 alembic==1.14.0
# via flask-migrate # via flask-migrate
amqp==5.3.1 amqp==5.3.1
# via kombu # via kombu
apispec==6.3.0 apispec[yaml]==6.3.0
# via flask-appbuilder # via flask-appbuilder
apsw==3.46.0.0 apsw==3.46.0.0
# via shillelagh # via shillelagh
@@ -20,7 +27,7 @@ attrs==24.2.0
babel==2.16.0 babel==2.16.0
# via flask-babel # via flask-babel
backoff==2.2.1 backoff==2.2.1
# via apache-superset (pyproject.toml) # via apache-superset
bcrypt==4.2.1 bcrypt==4.2.1
# via paramiko # via paramiko
billiard==4.2.1 billiard==4.2.1
@@ -28,7 +35,7 @@ billiard==4.2.1
blinker==1.9.0 blinker==1.9.0
# via flask # via flask
bottleneck==1.4.2 bottleneck==1.4.2
# via apache-superset (pyproject.toml) # via apache-superset
brotli==1.1.0 brotli==1.1.0
# via flask-compress # via flask-compress
cachelib==0.9.0 cachelib==0.9.0
@@ -40,7 +47,7 @@ cachetools==5.5.0
cattrs==24.1.2 cattrs==24.1.2
# via requests-cache # via requests-cache
celery==5.4.0 celery==5.4.0
# via apache-superset (pyproject.toml) # via apache-superset
certifi==2024.8.30 certifi==2024.8.30
# via requests # via requests
cffi==1.17.1 cffi==1.17.1
@@ -51,7 +58,7 @@ charset-normalizer==3.4.0
# via requests # via requests
click==8.1.7 click==8.1.7
# via # via
# apache-superset (pyproject.toml) # apache-superset
# celery # celery
# click-didyoumean # click-didyoumean
# click-option-group # click-option-group
@@ -62,22 +69,22 @@ click==8.1.7
click-didyoumean==0.3.1 click-didyoumean==0.3.1
# via celery # via celery
click-option-group==0.5.6 click-option-group==0.5.6
# via apache-superset (pyproject.toml) # via apache-superset
click-plugins==1.1.1 click-plugins==1.1.1
# via celery # via celery
click-repl==0.3.0 click-repl==0.3.0
# via celery # via celery
colorama==0.4.6 colorama==0.4.6
# via # via
# apache-superset (pyproject.toml) # apache-superset
# flask-appbuilder # flask-appbuilder
cron-descriptor==1.4.5 cron-descriptor==1.4.5
# via apache-superset (pyproject.toml) # via apache-superset
croniter==5.0.1 croniter==5.0.1
# via apache-superset (pyproject.toml) # via apache-superset
cryptography==43.0.3 cryptography==43.0.3
# via # via
# apache-superset (pyproject.toml) # apache-superset
# paramiko # paramiko
# pyopenssl # pyopenssl
defusedxml==0.7.1 defusedxml==0.7.1
@@ -85,7 +92,7 @@ defusedxml==0.7.1
deprecated==1.2.15 deprecated==1.2.15
# via limits # via limits
deprecation==2.1.0 deprecation==2.1.0
# via apache-superset (pyproject.toml) # via apache-superset
dnspython==2.7.0 dnspython==2.7.0
# via email-validator # via email-validator
email-validator==2.2.0 email-validator==2.2.0
@@ -96,7 +103,7 @@ exceptiongroup==1.2.2
# via cattrs # via cattrs
flask==2.3.3 flask==2.3.3
# via # via
# apache-superset (pyproject.toml) # apache-superset
# flask-appbuilder # flask-appbuilder
# flask-babel # flask-babel
# flask-caching # flask-caching
@@ -109,66 +116,66 @@ flask==2.3.3
# flask-sqlalchemy # flask-sqlalchemy
# flask-wtf # flask-wtf
flask-appbuilder==4.5.2 flask-appbuilder==4.5.2
# via apache-superset (pyproject.toml) # via apache-superset
flask-babel==2.0.0 flask-babel==2.0.0
# via flask-appbuilder # via flask-appbuilder
flask-caching==2.3.0 flask-caching==2.3.0
# via apache-superset (pyproject.toml) # via apache-superset
flask-compress==1.17 flask-compress==1.17
# via apache-superset (pyproject.toml) # via apache-superset
flask-jwt-extended==4.7.1 flask-jwt-extended==4.7.1
# via flask-appbuilder # via flask-appbuilder
flask-limiter==3.8.0 flask-limiter==3.8.0
# via flask-appbuilder # via flask-appbuilder
flask-login==0.6.3 flask-login==0.6.3
# via # via
# apache-superset (pyproject.toml) # apache-superset
# flask-appbuilder # flask-appbuilder
flask-migrate==3.1.0 flask-migrate==3.1.0
# via apache-superset (pyproject.toml) # via apache-superset
flask-session==0.8.0 flask-session==0.8.0
# via apache-superset (pyproject.toml) # via apache-superset
flask-sqlalchemy==2.5.1 flask-sqlalchemy==2.5.1
# via # via
# flask-appbuilder # flask-appbuilder
# flask-migrate # flask-migrate
flask-talisman==1.1.0 flask-talisman==1.1.0
# via apache-superset (pyproject.toml) # via apache-superset
flask-wtf==1.2.2 flask-wtf==1.2.2
# via # via
# apache-superset (pyproject.toml) # apache-superset
# flask-appbuilder # flask-appbuilder
func-timeout==4.3.5 func-timeout==4.3.5
# via apache-superset (pyproject.toml) # via apache-superset
geographiclib==2.0 geographiclib==2.0
# via geopy # via geopy
geopy==2.4.1 geopy==2.4.1
# via apache-superset (pyproject.toml) # via apache-superset
google-auth==2.36.0 google-auth==2.36.0
# via shillelagh # via shillelagh
greenlet==3.0.3 greenlet==3.0.3
# via # via
# -r requirements/base.in # -r requirements/base.in
# apache-superset (pyproject.toml) # apache-superset
# shillelagh # shillelagh
gunicorn==23.0.0 gunicorn==23.0.0
# via apache-superset (pyproject.toml) # via apache-superset
hashids==1.3.1 hashids==1.3.1
# via apache-superset (pyproject.toml) # via apache-superset
holidays==0.25 holidays==0.25
# via apache-superset (pyproject.toml) # via apache-superset
humanize==4.11.0 humanize==4.11.0
# via apache-superset (pyproject.toml) # via apache-superset
idna==3.10 idna==3.10
# via # via
# email-validator # email-validator
# requests # requests
importlib-metadata==8.5.0 importlib-metadata==8.5.0
# via apache-superset (pyproject.toml) # via apache-superset
importlib-resources==6.4.5 importlib-resources==6.4.5
# via limits # via limits
isodate==0.7.2 isodate==0.7.2
# via apache-superset (pyproject.toml) # via apache-superset
itsdangerous==2.2.0 itsdangerous==2.2.0
# via # via
# flask # flask
@@ -178,7 +185,7 @@ jinja2==3.1.4
# flask # flask
# flask-babel # flask-babel
jsonpath-ng==1.7.0 jsonpath-ng==1.7.0
# via apache-superset (pyproject.toml) # via apache-superset
jsonschema==4.17.3 jsonschema==4.17.3
# via flask-appbuilder # via flask-appbuilder
kombu==5.4.2 kombu==5.4.2
@@ -189,10 +196,10 @@ limits==3.13.0
# via flask-limiter # via flask-limiter
mako==1.3.6 mako==1.3.6
# via # via
# apache-superset (pyproject.toml)
# alembic # alembic
# apache-superset
markdown==3.7 markdown==3.7
# via apache-superset (pyproject.toml) # via apache-superset
markdown-it-py==3.0.0 markdown-it-py==3.0.0
# via rich # via rich
markupsafe==3.0.2 markupsafe==3.0.2
@@ -210,16 +217,16 @@ marshmallow-sqlalchemy==0.28.2
mdurl==0.1.2 mdurl==0.1.2
# via markdown-it-py # via markdown-it-py
msgpack==1.0.8 msgpack==1.0.8
# via apache-superset (pyproject.toml) # via apache-superset
msgspec==0.18.6 msgspec==0.18.6
# via flask-session # via flask-session
nh3==0.2.19 nh3==0.2.19
# via apache-superset (pyproject.toml) # via apache-superset
numexpr==2.10.2 numexpr==2.10.2
# via -r requirements/base.in # via -r requirements/base.in
numpy==1.23.5 numpy==1.23.5
# via # via
# apache-superset (pyproject.toml) # apache-superset
# bottleneck # bottleneck
# numexpr # numexpr
# pandas # pandas
@@ -232,7 +239,7 @@ ordered-set==4.1.0
# via flask-limiter # via flask-limiter
packaging==24.2 packaging==24.2
# via # via
# apache-superset (pyproject.toml) # apache-superset
# apispec # apispec
# deprecation # deprecation
# gunicorn # gunicorn
@@ -240,28 +247,28 @@ packaging==24.2
# marshmallow # marshmallow
# marshmallow-sqlalchemy # marshmallow-sqlalchemy
# shillelagh # shillelagh
pandas==2.0.3 pandas[excel]==2.0.3
# via apache-superset (pyproject.toml) # via apache-superset
paramiko==3.5.0 paramiko==3.5.0
# via # via
# apache-superset (pyproject.toml) # apache-superset
# sshtunnel # sshtunnel
parsedatetime==2.6 parsedatetime==2.6
# via apache-superset (pyproject.toml) # via apache-superset
pgsanity==0.2.9 pgsanity==0.2.9
# via apache-superset (pyproject.toml) # via apache-superset
platformdirs==3.8.1 platformdirs==3.8.1
# via requests-cache # via requests-cache
ply==3.11 ply==3.11
# via jsonpath-ng # via jsonpath-ng
polyline==2.0.2 polyline==2.0.2
# via apache-superset (pyproject.toml) # via apache-superset
prison==0.2.1 prison==0.2.1
# via flask-appbuilder # via flask-appbuilder
prompt-toolkit==3.0.48 prompt-toolkit==3.0.48
# via click-repl # via click-repl
pyarrow==14.0.2 pyarrow==14.0.2
# via apache-superset (pyproject.toml) # via apache-superset
pyasn1==0.6.1 pyasn1==0.6.1
# via # via
# pyasn1-modules # pyasn1-modules
@@ -274,7 +281,7 @@ pygments==2.18.0
# via rich # via rich
pyjwt==2.10.1 pyjwt==2.10.1
# via # via
# apache-superset (pyproject.toml) # apache-superset
# flask-appbuilder # flask-appbuilder
# flask-jwt-extended # flask-jwt-extended
pynacl==1.5.0 pynacl==1.5.0
@@ -282,12 +289,12 @@ pynacl==1.5.0
pyopenssl==24.2.1 pyopenssl==24.2.1
# via shillelagh # via shillelagh
pyparsing==3.2.0 pyparsing==3.2.0
# via apache-superset (pyproject.toml) # via apache-superset
pyrsistent==0.20.0 pyrsistent==0.20.0
# via jsonschema # via jsonschema
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
# via # via
# apache-superset (pyproject.toml) # apache-superset
# celery # celery
# croniter # croniter
# flask-appbuilder # flask-appbuilder
@@ -295,9 +302,9 @@ python-dateutil==2.9.0.post0
# pandas # pandas
# shillelagh # shillelagh
python-dotenv==1.0.1 python-dotenv==1.0.1
# via apache-superset (pyproject.toml) # via apache-superset
python-geohash==0.8.5 python-geohash==0.8.5
# via apache-superset (pyproject.toml) # via apache-superset
pytz==2024.2 pytz==2024.2
# via # via
# croniter # croniter
@@ -307,10 +314,10 @@ pyxlsb==1.0.10
# via pandas # via pandas
pyyaml==6.0.2 pyyaml==6.0.2
# via # via
# apache-superset (pyproject.toml) # apache-superset
# apispec # apispec
redis==4.6.0 redis==4.6.0
# via apache-superset (pyproject.toml) # via apache-superset
requests==2.32.2 requests==2.32.2
# via # via
# requests-cache # requests-cache
@@ -322,13 +329,13 @@ rich==13.9.4
rsa==4.9 rsa==4.9
# via google-auth # via google-auth
selenium==3.141.0 selenium==3.141.0
# via apache-superset (pyproject.toml) # via apache-superset
shillelagh==1.2.18 shillelagh[gsheetsapi]==1.2.18
# via apache-superset (pyproject.toml) # via apache-superset
shortid==0.1.2 shortid==0.1.2
# via apache-superset (pyproject.toml) # via apache-superset
simplejson==3.19.3 simplejson==3.19.3
# via apache-superset (pyproject.toml) # via apache-superset
six==1.16.0 six==1.16.0
# via # via
# prison # prison
@@ -336,11 +343,11 @@ six==1.16.0
# url-normalize # url-normalize
# wtforms-json # wtforms-json
slack-sdk==3.33.4 slack-sdk==3.33.4
# via apache-superset (pyproject.toml) # via apache-superset
sqlalchemy==1.4.54 sqlalchemy==1.4.54
# via # via
# apache-superset (pyproject.toml)
# alembic # alembic
# apache-superset
# flask-appbuilder # flask-appbuilder
# flask-sqlalchemy # flask-sqlalchemy
# marshmallow-sqlalchemy # marshmallow-sqlalchemy
@@ -348,20 +355,20 @@ sqlalchemy==1.4.54
# sqlalchemy-utils # sqlalchemy-utils
sqlalchemy-utils==0.38.3 sqlalchemy-utils==0.38.3
# via # via
# apache-superset (pyproject.toml) # apache-superset
# flask-appbuilder # flask-appbuilder
sqlglot==25.24.5 sqlglot==25.24.5
# via apache-superset (pyproject.toml) # via apache-superset
sqlparse==0.5.2 sqlparse==0.5.2
# via apache-superset (pyproject.toml) # via apache-superset
sshtunnel==0.4.0 sshtunnel==0.4.0
# via apache-superset (pyproject.toml) # via apache-superset
tabulate==0.8.10 tabulate==0.8.10
# via apache-superset (pyproject.toml) # via apache-superset
typing-extensions==4.12.2 typing-extensions==4.12.2
# via # via
# apache-superset (pyproject.toml)
# alembic # alembic
# apache-superset
# cattrs # cattrs
# flask-limiter # flask-limiter
# limits # limits
@@ -398,17 +405,17 @@ wrapt==1.17.0
# via deprecated # via deprecated
wtforms==3.2.1 wtforms==3.2.1
# via # via
# apache-superset (pyproject.toml) # apache-superset
# flask-appbuilder # flask-appbuilder
# flask-wtf # flask-wtf
# wtforms-json # wtforms-json
wtforms-json==0.3.5 wtforms-json==0.3.5
# via apache-superset (pyproject.toml) # via apache-superset
xlrd==2.0.1 xlrd==2.0.1
# via pandas # via pandas
xlsxwriter==3.0.9 xlsxwriter==3.0.9
# via # via
# apache-superset (pyproject.toml) # apache-superset
# pandas # pandas
zipp==3.21.0 zipp==3.21.0
# via importlib-metadata # via importlib-metadata
+2 -1
View File
@@ -16,4 +16,5 @@
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
-e .[development,bigquery,cors,druid,gevent,gsheets,mysql,postgres,presto,prophet,trino,thumbnails] -r base.in
-e .[development,bigquery,cors,druid,gevent,gsheets,mysql,playwright,postgres,presto,prophet,trino,thumbnails]
+38 -720
View File
@@ -1,294 +1,54 @@
# This file was autogenerated by uv via the following command: # SHA1:dc767a7288b56c785b0cd3c38e95e7b5e66be1ac
# uv pip compile requirements/development.in -c requirements/base.txt -o requirements/development.txt #
-e . # This file is autogenerated by pip-compile-multi
# via -r requirements/development.in # To update, run:
alembic==1.14.0 #
# pip-compile-multi
#
-r base.txt
-e file:.
# via # via
# -c requirements/base.txt # -r /Users/max/code/superset/requirements/base.in
# flask-migrate # -r requirements/development.in
amqp==5.3.1 build==1.2.1
# via # via pip-tools
# -c requirements/base.txt
# kombu
apispec==6.3.0
# via
# -c requirements/base.txt
# flask-appbuilder
apsw==3.46.0.0
# via
# -c requirements/base.txt
# shillelagh
async-timeout==4.0.3
# via
# -c requirements/base.txt
# redis
attrs==24.2.0
# via
# -c requirements/base.txt
# cattrs
# jsonschema
# requests-cache
babel==2.16.0
# via
# -c requirements/base.txt
# flask-babel
backoff==2.2.1
# via
# -c requirements/base.txt
# apache-superset
bcrypt==4.2.1
# via
# -c requirements/base.txt
# paramiko
billiard==4.2.1
# via
# -c requirements/base.txt
# celery
blinker==1.9.0
# via
# -c requirements/base.txt
# flask
bottleneck==1.4.2
# via
# -c requirements/base.txt
# apache-superset
brotli==1.1.0
# via
# -c requirements/base.txt
# flask-compress
cachelib==0.9.0
# via
# -c requirements/base.txt
# flask-caching
# flask-session
cachetools==5.5.0
# via
# -c requirements/base.txt
# google-auth
cattrs==24.1.2
# via
# -c requirements/base.txt
# requests-cache
celery==5.4.0
# via
# -c requirements/base.txt
# apache-superset
certifi==2024.8.30
# via
# -c requirements/base.txt
# requests
cffi==1.17.1
# via
# -c requirements/base.txt
# cryptography
# pynacl
cfgv==3.4.0 cfgv==3.4.0
# via pre-commit # via pre-commit
charset-normalizer==3.4.0
# via
# -c requirements/base.txt
# requests
click==8.1.7
# via
# -c requirements/base.txt
# apache-superset
# celery
# click-didyoumean
# click-option-group
# click-plugins
# click-repl
# flask
# flask-appbuilder
click-didyoumean==0.3.1
# via
# -c requirements/base.txt
# celery
click-option-group==0.5.6
# via
# -c requirements/base.txt
# apache-superset
click-plugins==1.1.1
# via
# -c requirements/base.txt
# celery
click-repl==0.3.0
# via
# -c requirements/base.txt
# celery
cmdstanpy==1.1.0 cmdstanpy==1.1.0
# via prophet # via prophet
colorama==0.4.6
# via
# -c requirements/base.txt
# apache-superset
# flask-appbuilder
contourpy==1.0.7 contourpy==1.0.7
# via matplotlib # via matplotlib
coverage==7.6.8 coverage[toml]==7.6.8
# via pytest-cov # via pytest-cov
cron-descriptor==1.4.5
# via
# -c requirements/base.txt
# apache-superset
croniter==5.0.1
# via
# -c requirements/base.txt
# apache-superset
cryptography==43.0.3
# via
# -c requirements/base.txt
# apache-superset
# paramiko
# pyopenssl
cycler==0.12.1 cycler==0.12.1
# via matplotlib # via matplotlib
db-dtypes==1.3.1 db-dtypes==1.3.1
# via pandas-gbq # via pandas-gbq
defusedxml==0.7.1
# via
# -c requirements/base.txt
# odfpy
deprecated==1.2.15
# via
# -c requirements/base.txt
# limits
deprecation==2.1.0
# via
# -c requirements/base.txt
# apache-superset
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
dnspython==2.7.0
# via
# -c requirements/base.txt
# email-validator
docker==7.0.0 docker==7.0.0
# via apache-superset # via apache-superset
email-validator==2.2.0
# via
# -c requirements/base.txt
# flask-appbuilder
et-xmlfile==2.0.0
# via
# -c requirements/base.txt
# openpyxl
exceptiongroup==1.2.2
# via
# -c requirements/base.txt
# cattrs
# pytest
filelock==3.12.2 filelock==3.12.2
# via virtualenv # via virtualenv
flask==2.3.3
# via
# -c requirements/base.txt
# apache-superset
# flask-appbuilder
# flask-babel
# flask-caching
# flask-compress
# flask-cors
# flask-jwt-extended
# flask-limiter
# flask-login
# flask-migrate
# flask-session
# flask-sqlalchemy
# flask-testing
# flask-wtf
flask-appbuilder==4.5.2
# via
# -c requirements/base.txt
# apache-superset
flask-babel==2.0.0
# via
# -c requirements/base.txt
# flask-appbuilder
flask-caching==2.3.0
# via
# -c requirements/base.txt
# apache-superset
flask-compress==1.17
# via
# -c requirements/base.txt
# apache-superset
flask-cors==4.0.0 flask-cors==4.0.0
# via apache-superset # via apache-superset
flask-jwt-extended==4.7.1
# via
# -c requirements/base.txt
# flask-appbuilder
flask-limiter==3.8.0
# via
# -c requirements/base.txt
# flask-appbuilder
flask-login==0.6.3
# via
# -c requirements/base.txt
# apache-superset
# flask-appbuilder
flask-migrate==3.1.0
# via
# -c requirements/base.txt
# apache-superset
flask-session==0.8.0
# via
# -c requirements/base.txt
# apache-superset
flask-sqlalchemy==2.5.1
# via
# -c requirements/base.txt
# flask-appbuilder
# flask-migrate
flask-talisman==1.1.0
# via
# -c requirements/base.txt
# apache-superset
flask-testing==0.8.1 flask-testing==0.8.1
# via apache-superset # via apache-superset
flask-wtf==1.2.2
# via
# -c requirements/base.txt
# apache-superset
# flask-appbuilder
fonttools==4.55.0 fonttools==4.55.0
# via matplotlib # via matplotlib
freezegun==1.5.1 freezegun==1.5.1
# via apache-superset # via apache-superset
func-timeout==4.3.5
# via
# -c requirements/base.txt
# apache-superset
future==1.0.0 future==1.0.0
# via pyhive # via pyhive
geographiclib==2.0
# via
# -c requirements/base.txt
# geopy
geopy==2.4.1
# via
# -c requirements/base.txt
# apache-superset
gevent==24.2.1 gevent==24.2.1
# via apache-superset # via apache-superset
google-api-core==2.23.0 google-api-core[grpc]==2.23.0
# via # via
# google-cloud-bigquery # google-cloud-bigquery
# google-cloud-bigquery-storage # google-cloud-bigquery-storage
# google-cloud-core # google-cloud-core
# pandas-gbq # pandas-gbq
# sqlalchemy-bigquery # sqlalchemy-bigquery
google-auth==2.36.0
# via
# -c requirements/base.txt
# google-api-core
# google-auth-oauthlib
# google-cloud-bigquery
# google-cloud-core
# pandas-gbq
# pydata-google-auth
# shillelagh
# sqlalchemy-bigquery
google-auth-oauthlib==1.2.1 google-auth-oauthlib==1.2.1
# via # via
# pandas-gbq # pandas-gbq
@@ -310,12 +70,6 @@ googleapis-common-protos==1.66.0
# via # via
# google-api-core # google-api-core
# grpcio-status # grpcio-status
greenlet==3.0.3
# via
# -c requirements/base.txt
# apache-superset
# gevent
# shillelagh
grpcio==1.68.0 grpcio==1.68.0
# via # via
# apache-superset # apache-superset
@@ -323,241 +77,50 @@ grpcio==1.68.0
# grpcio-status # grpcio-status
grpcio-status==1.60.1 grpcio-status==1.60.1
# via google-api-core # via google-api-core
gunicorn==23.0.0
# via
# -c requirements/base.txt
# apache-superset
hashids==1.3.1
# via
# -c requirements/base.txt
# apache-superset
holidays==0.25
# via
# -c requirements/base.txt
# apache-superset
# prophet
humanize==4.11.0
# via
# -c requirements/base.txt
# apache-superset
identify==2.5.36 identify==2.5.36
# via pre-commit # via pre-commit
idna==3.10
# via
# -c requirements/base.txt
# email-validator
# requests
importlib-metadata==8.5.0
# via
# -c requirements/base.txt
# apache-superset
importlib-resources==6.4.5
# via
# -c requirements/base.txt
# limits
# prophet
iniconfig==2.0.0 iniconfig==2.0.0
# via pytest # via pytest
isodate==0.7.2
# via
# -c requirements/base.txt
# apache-superset
itsdangerous==2.2.0
# via
# -c requirements/base.txt
# flask
# flask-wtf
jinja2==3.1.4
# via
# -c requirements/base.txt
# flask
# flask-babel
jsonpath-ng==1.7.0
# via
# -c requirements/base.txt
# apache-superset
jsonschema==4.17.3
# via
# -c requirements/base.txt
# flask-appbuilder
# jsonschema-spec
# openapi-schema-validator
# openapi-spec-validator
jsonschema-spec==0.1.6 jsonschema-spec==0.1.6
# via openapi-spec-validator # via openapi-spec-validator
kiwisolver==1.4.7 kiwisolver==1.4.7
# via matplotlib # via matplotlib
kombu==5.4.2
# via
# -c requirements/base.txt
# celery
korean-lunar-calendar==0.3.1
# via
# -c requirements/base.txt
# holidays
lazy-object-proxy==1.10.0 lazy-object-proxy==1.10.0
# via openapi-spec-validator # via openapi-spec-validator
limits==3.13.0
# via
# -c requirements/base.txt
# flask-limiter
mako==1.3.6
# via
# -c requirements/base.txt
# alembic
# apache-superset
markdown==3.7
# via
# -c requirements/base.txt
# apache-superset
markdown-it-py==3.0.0
# via
# -c requirements/base.txt
# rich
markupsafe==3.0.2
# via
# -c requirements/base.txt
# jinja2
# mako
# werkzeug
# wtforms
marshmallow==3.23.1
# via
# -c requirements/base.txt
# flask-appbuilder
# marshmallow-sqlalchemy
marshmallow-sqlalchemy==0.28.2
# via
# -c requirements/base.txt
# flask-appbuilder
matplotlib==3.9.0 matplotlib==3.9.0
# via prophet # via prophet
mdurl==0.1.2
# via
# -c requirements/base.txt
# markdown-it-py
msgpack==1.0.8
# via
# -c requirements/base.txt
# apache-superset
msgspec==0.18.6
# via
# -c requirements/base.txt
# flask-session
mysqlclient==2.2.6 mysqlclient==2.2.6
# via apache-superset # via apache-superset
nh3==0.2.19
# via
# -c requirements/base.txt
# apache-superset
nodeenv==1.8.0 nodeenv==1.8.0
# via pre-commit # via pre-commit
numpy==1.23.5
# via
# -c requirements/base.txt
# apache-superset
# bottleneck
# cmdstanpy
# contourpy
# db-dtypes
# matplotlib
# pandas
# pandas-gbq
# prophet
# pyarrow
oauthlib==3.2.2 oauthlib==3.2.2
# via requests-oauthlib # via requests-oauthlib
odfpy==1.4.1
# via
# -c requirements/base.txt
# pandas
openapi-schema-validator==0.4.4 openapi-schema-validator==0.4.4
# via openapi-spec-validator # via openapi-spec-validator
openapi-spec-validator==0.5.6 openapi-spec-validator==0.5.6
# via apache-superset # via apache-superset
openpyxl==3.1.5
# via
# -c requirements/base.txt
# pandas
ordered-set==4.1.0
# via
# -c requirements/base.txt
# flask-limiter
packaging==24.2
# via
# -c requirements/base.txt
# apache-superset
# apispec
# db-dtypes
# deprecation
# docker
# google-cloud-bigquery
# gunicorn
# limits
# marshmallow
# marshmallow-sqlalchemy
# matplotlib
# pytest
# shillelagh
# sqlalchemy-bigquery
pandas==2.0.3
# via
# -c requirements/base.txt
# apache-superset
# cmdstanpy
# db-dtypes
# pandas-gbq
# prophet
pandas-gbq==0.19.1 pandas-gbq==0.19.1
# via apache-superset # via apache-superset
parameterized==0.9.0 parameterized==0.9.0
# via apache-superset # via apache-superset
paramiko==3.5.0
# via
# -c requirements/base.txt
# apache-superset
# sshtunnel
parsedatetime==2.6
# via
# -c requirements/base.txt
# apache-superset
pathable==0.4.3 pathable==0.4.3
# via jsonschema-spec # via jsonschema-spec
pgsanity==0.2.9
# via
# -c requirements/base.txt
# apache-superset
pillow==10.3.0 pillow==10.3.0
# via # via
# apache-superset # apache-superset
# matplotlib # matplotlib
platformdirs==3.8.1 pip-compile-multi==2.6.3
# via # via apache-superset
# -c requirements/base.txt pip-tools==7.4.1
# requests-cache # via pip-compile-multi
# virtualenv playwright==1.42.0
# via apache-superset
pluggy==1.5.0 pluggy==1.5.0
# via pytest # via pytest
ply==3.11
# via
# -c requirements/base.txt
# jsonpath-ng
polyline==2.0.2
# via
# -c requirements/base.txt
# apache-superset
pre-commit==4.0.1 pre-commit==4.0.1
# via apache-superset # via apache-superset
prison==0.2.1
# via
# -c requirements/base.txt
# flask-appbuilder
progress==1.6 progress==1.6
# via apache-superset # via apache-superset
prompt-toolkit==3.0.48
# via
# -c requirements/base.txt
# click-repl
prophet==1.1.5 prophet==1.1.5
# via apache-superset # via apache-superset
proto-plus==1.25.0 proto-plus==1.25.0
@@ -575,64 +138,22 @@ psutil==6.1.0
# via apache-superset # via apache-superset
psycopg2-binary==2.9.6 psycopg2-binary==2.9.6
# via apache-superset # via apache-superset
pyarrow==14.0.2
# via
# -c requirements/base.txt
# apache-superset
# db-dtypes
# pandas-gbq
pyasn1==0.6.1
# via
# -c requirements/base.txt
# pyasn1-modules
# python-ldap
# rsa
pyasn1-modules==0.4.1
# via
# -c requirements/base.txt
# google-auth
# python-ldap
pycparser==2.22
# via
# -c requirements/base.txt
# cffi
pydata-google-auth==1.9.0 pydata-google-auth==1.9.0
# via pandas-gbq # via pandas-gbq
pydruid==0.6.9 pydruid==0.6.9
# via apache-superset # via apache-superset
pyee==11.0.1
# via playwright
pyfakefs==5.3.5 pyfakefs==5.3.5
# via apache-superset # via apache-superset
pygments==2.18.0 pyhive[presto]==0.7.0
# via
# -c requirements/base.txt
# rich
pyhive==0.7.0
# via apache-superset # via apache-superset
pyinstrument==4.4.0 pyinstrument==4.4.0
# via apache-superset # via apache-superset
pyjwt==2.10.1 pyproject-hooks==1.2.0
# via # via
# -c requirements/base.txt # build
# apache-superset # pip-tools
# flask-appbuilder
# flask-jwt-extended
pynacl==1.5.0
# via
# -c requirements/base.txt
# paramiko
pyopenssl==24.2.1
# via
# -c requirements/base.txt
# shillelagh
pyparsing==3.2.0
# via
# -c requirements/base.txt
# apache-superset
# matplotlib
pyrsistent==0.20.0
# via
# -c requirements/base.txt
# jsonschema
pytest==7.4.4 pytest==7.4.4
# via # via
# apache-superset # apache-superset
@@ -642,248 +163,45 @@ pytest-cov==6.0.0
# via apache-superset # via apache-superset
pytest-mock==3.10.0 pytest-mock==3.10.0
# via apache-superset # via apache-superset
python-dateutil==2.9.0.post0
# via
# -c requirements/base.txt
# apache-superset
# celery
# croniter
# flask-appbuilder
# freezegun
# google-cloud-bigquery
# holidays
# matplotlib
# pandas
# pyhive
# shillelagh
# trino
python-dotenv==1.0.1
# via
# -c requirements/base.txt
# apache-superset
python-geohash==0.8.5
# via
# -c requirements/base.txt
# apache-superset
python-ldap==3.4.4 python-ldap==3.4.4
# via apache-superset # via apache-superset
pytz==2024.2
# via
# -c requirements/base.txt
# croniter
# flask-babel
# pandas
# trino
pyxlsb==1.0.10
# via
# -c requirements/base.txt
# pandas
pyyaml==6.0.2
# via
# -c requirements/base.txt
# apache-superset
# apispec
# jsonschema-spec
# pre-commit
redis==4.6.0
# via
# -c requirements/base.txt
# apache-superset
requests==2.32.2
# via
# -c requirements/base.txt
# docker
# google-api-core
# google-cloud-bigquery
# jsonschema-spec
# pydruid
# pyhive
# requests-cache
# requests-oauthlib
# shillelagh
# trino
requests-cache==1.2.0
# via
# -c requirements/base.txt
# shillelagh
requests-oauthlib==2.0.0 requests-oauthlib==2.0.0
# via google-auth-oauthlib # via google-auth-oauthlib
rfc3339-validator==0.1.4 rfc3339-validator==0.1.4
# via openapi-schema-validator # via openapi-schema-validator
rich==13.9.4
# via
# -c requirements/base.txt
# flask-limiter
rsa==4.9
# via
# -c requirements/base.txt
# google-auth
ruff==0.8.0 ruff==0.8.0
# via apache-superset # via apache-superset
selenium==3.141.0
# via
# -c requirements/base.txt
# apache-superset
setuptools==75.6.0
# via
# nodeenv
# pandas-gbq
# pydata-google-auth
# zope-event
# zope-interface
shillelagh==1.2.18
# via
# -c requirements/base.txt
# apache-superset
shortid==0.1.2
# via
# -c requirements/base.txt
# apache-superset
simplejson==3.19.3
# via
# -c requirements/base.txt
# apache-superset
six==1.16.0
# via
# -c requirements/base.txt
# prison
# python-dateutil
# rfc3339-validator
# url-normalize
# wtforms-json
slack-sdk==3.33.4
# via
# -c requirements/base.txt
# apache-superset
sqlalchemy==1.4.54
# via
# -c requirements/base.txt
# alembic
# apache-superset
# flask-appbuilder
# flask-sqlalchemy
# marshmallow-sqlalchemy
# shillelagh
# sqlalchemy-bigquery
# sqlalchemy-utils
sqlalchemy-bigquery==1.12.0 sqlalchemy-bigquery==1.12.0
# via apache-superset # via apache-superset
sqlalchemy-utils==0.38.3
# via
# -c requirements/base.txt
# apache-superset
# flask-appbuilder
sqlglot==25.24.5
# via
# -c requirements/base.txt
# apache-superset
sqloxide==0.1.51 sqloxide==0.1.51
# via apache-superset # via apache-superset
sqlparse==0.5.2
# via
# -c requirements/base.txt
# apache-superset
sshtunnel==0.4.0
# via
# -c requirements/base.txt
# apache-superset
statsd==4.0.1 statsd==4.0.1
# via apache-superset # via apache-superset
tabulate==0.8.10 tomli==2.1.0
# via
# -c requirements/base.txt
# apache-superset
tomli==2.2.1
# via # via
# build
# coverage # coverage
# pip-tools
# pytest # pytest
toposort==1.10
# via pip-compile-multi
tqdm==4.67.1 tqdm==4.67.1
# via # via
# cmdstanpy # cmdstanpy
# prophet # prophet
trino==0.330.0 trino==0.330.0
# via apache-superset # via apache-superset
typing-extensions==4.12.2
# via
# -c requirements/base.txt
# alembic
# apache-superset
# cattrs
# flask-limiter
# limits
# rich
# shillelagh
tzdata==2024.2
# via
# -c requirements/base.txt
# celery
# kombu
# pandas
tzlocal==5.2 tzlocal==5.2
# via trino # via trino
url-normalize==1.4.3
# via
# -c requirements/base.txt
# requests-cache
urllib3==1.26.18
# via
# -c requirements/base.txt
# docker
# requests
# requests-cache
# selenium
vine==5.1.0
# via
# -c requirements/base.txt
# amqp
# celery
# kombu
virtualenv==20.23.1 virtualenv==20.23.1
# via pre-commit # via pre-commit
wcwidth==0.2.13 wheel==0.45.1
# via # via pip-tools
# -c requirements/base.txt
# prompt-toolkit
werkzeug==3.1.3
# via
# -c requirements/base.txt
# flask
# flask-appbuilder
# flask-jwt-extended
# flask-login
wrapt==1.17.0
# via
# -c requirements/base.txt
# deprecated
wtforms==3.2.1
# via
# -c requirements/base.txt
# apache-superset
# flask-appbuilder
# flask-wtf
# wtforms-json
wtforms-json==0.3.5
# via
# -c requirements/base.txt
# apache-superset
xlrd==2.0.1
# via
# -c requirements/base.txt
# pandas
xlsxwriter==3.0.9
# via
# -c requirements/base.txt
# apache-superset
# pandas
zipp==3.21.0
# via
# -c requirements/base.txt
# importlib-metadata
zope-event==5.0 zope-event==5.0
# via gevent # via gevent
zope-interface==5.4.0 zope-interface==5.4.0
# via gevent # via gevent
zstandard==0.23.0
# via # The following packages are considered to be unsafe in a requirements file:
# -c requirements/base.txt # pip
# flask-compress # setuptools
+7 -2
View File
@@ -1,4 +1,9 @@
# This file was autogenerated by uv via the following command: # SHA1:cad160f3d4cd7c33896f42a479eeaa1b5bedc5fb
# uv pip compile requirements/translations.in -o requirements/translations.txt #
# This file is autogenerated by pip-compile-multi
# To update, run:
#
# pip-compile-multi
#
babel==2.16.0 babel==2.16.0
# via -r requirements/translations.in # via -r requirements/translations.in
+3 -3
View File
@@ -70,7 +70,7 @@ def extract_modified_tables(module: ModuleType) -> set[str]:
return tables return tables
def find_models(module: ModuleType) -> list[type[Model]]: # noqa: C901 def find_models(module: ModuleType) -> list[type[Model]]:
""" """
Find all models in a migration script. Find all models in a migration script.
""" """
@@ -94,7 +94,7 @@ def find_models(module: ModuleType) -> list[type[Model]]: # noqa: C901
# downgrade # downgrade
sqlalchemy_uri = current_app.config["SQLALCHEMY_DATABASE_URI"] sqlalchemy_uri = current_app.config["SQLALCHEMY_DATABASE_URI"]
engine = create_engine(sqlalchemy_uri) engine = create_engine(sqlalchemy_uri)
Base = automap_base() # noqa: N806 Base = automap_base()
Base.prepare(engine, reflect=True) Base.prepare(engine, reflect=True)
seen = set() seen = set()
while tables: while tables:
@@ -138,7 +138,7 @@ def find_models(module: ModuleType) -> list[type[Model]]: # noqa: C901
@click.option("--limit", default=1000, help="Maximum number of entities.") @click.option("--limit", default=1000, help="Maximum number of entities.")
@click.option("--force", is_flag=True, help="Do not prompt for confirmation.") @click.option("--force", is_flag=True, help="Do not prompt for confirmation.")
@click.option("--no-auto-cleanup", is_flag=True, help="Do not remove created models.") @click.option("--no-auto-cleanup", is_flag=True, help="Do not remove created models.")
def main( # noqa: C901 def main(
filepath: str, limit: int = 1000, force: bool = False, no_auto_cleanup: bool = False filepath: str, limit: int = 1000, force: bool = False, no_auto_cleanup: bool = False
) -> None: ) -> None:
auto_cleanup = not no_auto_cleanup auto_cleanup = not no_auto_cleanup
+2 -2
View File
@@ -49,7 +49,7 @@ github_repo = os.environ.get("GITHUB_REPOSITORY", "apache/superset")
def request( def request(
method: Literal["GET", "POST", "DELETE", "PUT"], endpoint: str, **kwargs: Any method: Literal["GET", "POST", "DELETE", "PUT"], endpoint: str, **kwargs: Any
) -> dict[str, Any]: ) -> dict[str, Any]:
resp = requests.request( # noqa: S113 resp = requests.request(
method, method,
f"https://api.github.com/{endpoint.lstrip('/')}", f"https://api.github.com/{endpoint.lstrip('/')}",
headers={"Authorization": f"Bearer {github_token}"}, headers={"Authorization": f"Bearer {github_token}"},
@@ -152,7 +152,7 @@ Date: {date_str}
help="Whether to also cancel running workflows.", help="Whether to also cancel running workflows.",
) )
@click.argument("branch_or_pull", required=False) @click.argument("branch_or_pull", required=False)
def cancel_github_workflows( # noqa: C901 def cancel_github_workflows(
branch_or_pull: Optional[str], branch_or_pull: Optional[str],
repo: str, repo: str,
event: list[str], event: list[str],
+5 -5
View File
@@ -51,12 +51,12 @@ GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN")
def fetch_files_github_api(url: str): # type: ignore def fetch_files_github_api(url: str): # type: ignore
"""Fetches data using GitHub API.""" """Fetches data using GitHub API."""
req = Request(url) # noqa: S310 req = Request(url)
req.add_header("Authorization", f"Bearer {GITHUB_TOKEN}") req.add_header("Authorization", f"Bearer {GITHUB_TOKEN}")
req.add_header("Accept", "application/vnd.github.v3+json") req.add_header("Accept", "application/vnd.github.v3+json")
print(f"Fetching from {url}") print(f"Fetching from {url}")
with urlopen(req) as response: # noqa: S310 with urlopen(req) as response:
body = response.read() body = response.read()
return json.loads(body) return json.loads(body)
@@ -130,7 +130,7 @@ def main(event_type: str, sha: str, repo: str) -> None:
) )
# Output results # Output results
output_path = os.getenv("GITHUB_OUTPUT") or "/tmp/GITHUB_OUTPUT.txt" # noqa: S108 output_path = os.getenv("GITHUB_OUTPUT") or "/tmp/GITHUB_OUTPUT.txt"
with open(output_path, "a") as f: with open(output_path, "a") as f:
for check, changed in changes_detected.items(): for check, changed in changes_detected.items():
if changed: if changed:
@@ -139,8 +139,8 @@ def main(event_type: str, sha: str, repo: str) -> None:
def get_git_sha() -> str: def get_git_sha() -> str:
return os.getenv("GITHUB_SHA") or subprocess.check_output( # noqa: S603 return os.getenv("GITHUB_SHA") or subprocess.check_output(
["git", "rev-parse", "HEAD"] # noqa: S607 ["git", "rev-parse", "HEAD"]
).strip().decode("utf-8") ).strip().decode("utf-8")
+6 -7
View File
@@ -47,7 +47,7 @@ class Requirement:
def get_version(self) -> Optional[str]: def get_version(self) -> Optional[str]:
try: try:
version = subprocess.check_output(self.command, shell=True).decode().strip() # noqa: S602 version = subprocess.check_output(self.command, shell=True).decode().strip()
if self.version_post_process: if self.version_post_process:
version = self.version_post_process(version) version = self.version_post_process(version)
return version.split()[-1] return version.split()[-1]
@@ -76,7 +76,7 @@ class Requirement:
def format_result(self) -> str: def format_result(self) -> str:
ideal_range_str = f"{self.ideal_range[0]} - {self.ideal_range[1]}" ideal_range_str = f"{self.ideal_range[0]} - {self.ideal_range[1]}"
supported_range_str = f"{self.supported_range[0]} - {self.supported_range[1]}" supported_range_str = f"{self.supported_range[0]} - {self.supported_range[1]}"
return f"{self.status.split()[0]} {self.name:<25} {self.version or 'N/A':<25} {ideal_range_str:<25} {supported_range_str:<25}" # noqa: E501 return f"{self.status.split()[0]} {self.name:<25} {self.version or 'N/A':<25} {ideal_range_str:<25} {supported_range_str:<25}"
def check_memory(min_gb: int) -> str: def check_memory(min_gb: int) -> str:
@@ -101,9 +101,8 @@ def get_cpu_info() -> str:
def get_docker_platform() -> str: def get_docker_platform() -> str:
try: try:
output = ( output = (
subprocess.check_output( # noqa: S602 subprocess.check_output(
"docker info --format '{{.OperatingSystem}}'", # noqa: S607 "docker info --format '{{.OperatingSystem}}'", shell=True
shell=True, # noqa: S607
) )
.decode() .decode()
.strip() .strip()
@@ -118,7 +117,7 @@ def get_docker_platform() -> str:
@click.command( @click.command(
help=""" help="""
This script checks the local environment for various software versions and other requirements, providing feedback on whether they are ideal, supported, or unsupported. This script checks the local environment for various software versions and other requirements, providing feedback on whether they are ideal, supported, or unsupported.
""" # noqa: E501 """
) )
@click.option( @click.option(
"--docker", is_flag=True, help="Check Docker and Docker Compose requirements" "--docker", is_flag=True, help="Check Docker and Docker Compose requirements"
@@ -129,7 +128,7 @@ This script checks the local environment for various software versions and other
help="Check frontend requirements (npm, Node.js, memory)", help="Check frontend requirements (npm, Node.js, memory)",
) )
@click.option("--backend", is_flag=True, help="Check backend requirements (Python)") @click.option("--backend", is_flag=True, help="Check backend requirements (Python)")
def main(docker: bool, frontend: bool, backend: bool) -> None: # noqa: C901 def main(docker: bool, frontend: bool, backend: bool) -> None:
requirements = [ requirements = [
Requirement( Requirement(
"python", "python",
+1 -1
View File
@@ -74,7 +74,7 @@ def run_cypress_for_test_file(
print(f"DRY RUN: {cmd}") print(f"DRY RUN: {cmd}")
return 0 return 0
process = subprocess.Popen( # noqa: S602 process = subprocess.Popen(
cmd, cmd,
shell=True, shell=True,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
+1 -1
View File
@@ -171,7 +171,7 @@ def generate_erd(file_path: str) -> None:
""" """
data = introspect_models() data = introspect_models()
templates_path = os.path.dirname(__file__) templates_path = os.path.dirname(__file__)
env = jinja2.Environment(loader=jinja2.FileSystemLoader(templates_path)) # noqa: S701 env = jinja2.Environment(loader=jinja2.FileSystemLoader(templates_path))
# Load the template # Load the template
template = env.get_template("erd.template.puml") template = env.get_template("erd.template.puml")
-30
View File
@@ -1,30 +0,0 @@
#!/usr/bin/env bash
#
# 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.
#
set -e
ADDITIONAL_ARGS="$@"
# Generate the requirements/base.txt file
uv pip compile pyproject.toml requirements/base.in -o requirements/base.txt $ADDITIONAL_ARGS
# Generate the requirements/development.txt file, making sure requirements/base.txt is a constraint to keep the versions in sync
uv pip compile requirements/development.in -c requirements/base.txt -o requirements/development.txt $ADDITIONAL_ARGS
uv pip compile requirements/translations.in -o requirements/translations.txt $ADDITIONAL_ARGS
+2 -2
View File
@@ -30,7 +30,7 @@ with open(PACKAGE_JSON) as package_file:
def get_git_sha() -> str: def get_git_sha() -> str:
try: try:
output = subprocess.check_output(["git", "rev-parse", "HEAD"]) # noqa: S603, S607 output = subprocess.check_output(["git", "rev-parse", "HEAD"])
return output.decode().strip() return output.decode().strip()
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
return "" return ""
@@ -58,7 +58,7 @@ setup(
zip_safe=False, zip_safe=False,
entry_points={ entry_points={
"console_scripts": ["superset=superset.cli.main:superset"], "console_scripts": ["superset=superset.cli.main:superset"],
# the `postgres` and `postgres+psycopg2://` schemes were removed in SQLAlchemy 1.4 # noqa: E501 # the `postgres` and `postgres+psycopg2://` schemes were removed in SQLAlchemy 1.4
# add an alias here to prevent breaking existing databases # add an alias here to prevent breaking existing databases
"sqlalchemy.dialects": [ "sqlalchemy.dialects": [
"postgres.psycopg2 = sqlalchemy.dialects.postgresql:dialect", "postgres.psycopg2 = sqlalchemy.dialects.postgresql:dialect",
@@ -57,7 +57,7 @@ const drillBy = (targetDrillByColumn: string, isLegacy = false) => {
cy.get('.ant-dropdown:not(.ant-dropdown-hidden)') cy.get('.ant-dropdown:not(.ant-dropdown-hidden)')
.first() .first()
.find("[role='menu'] [role='menuitem'] [title='Drill by']") .find("[role='menu'] [role='menuitem'] [title='Drill by']")
.trigger('mouseover', { force: true }); .trigger('mouseover');
cy.get( cy.get(
'.ant-dropdown-menu-submenu:not(.ant-dropdown-menu-hidden) [data-test="drill-by-submenu"]', '.ant-dropdown-menu-submenu:not(.ant-dropdown-menu-hidden) [data-test="drill-by-submenu"]',
) )
@@ -51,7 +51,7 @@ function openProperties() {
cy.getBySel('header-actions-menu') cy.getBySel('header-actions-menu')
.contains('Edit properties') .contains('Edit properties')
.click({ force: true }); .click({ force: true });
cy.get('.antd5-modal-body').should('be.visible'); cy.get('.ant-modal-body').should('be.visible');
}); });
} }
@@ -60,7 +60,7 @@ function openExploreProperties() {
cy.get('.ant-dropdown-menu') cy.get('.ant-dropdown-menu')
.contains('Edit chart properties') .contains('Edit chart properties')
.click({ force: true }); .click({ force: true });
cy.get('.antd5-modal-body').should('be.visible'); cy.get('.ant-modal-body').should('be.visible');
} }
function assertMetadata(text: string) { function assertMetadata(text: string) {
@@ -77,7 +77,7 @@ function assertMetadata(text: string) {
} }
function openAdvancedProperties() { function openAdvancedProperties() {
cy.get('.antd5-modal-body') cy.get('.ant-modal-body')
.contains('Advanced') .contains('Advanced')
.should('be.visible') .should('be.visible')
.click({ force: true }); .click({ force: true });
@@ -1093,14 +1093,14 @@ describe('Dashboard edit', () => {
applyChanges(); applyChanges();
}); });
it.skip('should not accept an invalid color scheme', () => { it('should not accept an invalid color scheme', () => {
openAdvancedProperties(); openAdvancedProperties();
clearMetadata(); clearMetadata();
// allow console error // allow console error
cy.allowConsoleErrors(['Error: A valid color scheme is required']); cy.allowConsoleErrors(['Error: A valid color scheme is required']);
writeMetadata('{"color_scheme":"wrongcolorscheme"}'); writeMetadata('{"color_scheme":"wrongcolorscheme"}');
applyChanges(); applyChanges();
cy.get('.antd5-modal-body') cy.get('.ant-modal-body')
.contains('A valid color scheme is required') .contains('A valid color scheme is required')
.should('be.visible'); .should('be.visible');
}); });
@@ -56,7 +56,7 @@ describe('Datasource control', () => {
cy.focused().type(`${newMetricName}{enter}`); cy.focused().type(`${newMetricName}{enter}`);
cy.get('[data-test="datasource-modal-save"]').click(); cy.get('[data-test="datasource-modal-save"]').click();
cy.get('.antd5-modal-confirm-btns button').contains('OK').click(); cy.get('.ant-modal-confirm-btns button').contains('OK').click();
// select new metric // select new metric
cy.get('[data-test=metrics]') cy.get('[data-test=metrics]')
.contains('Drop columns/metrics here or click') .contains('Drop columns/metrics here or click')
@@ -68,7 +68,7 @@ describe('Datasource control', () => {
// delete metric // delete metric
cy.get('[data-test="datasource-menu-trigger"]').click(); cy.get('[data-test="datasource-menu-trigger"]').click();
cy.get('[data-test="edit-dataset"]').click(); cy.get('[data-test="edit-dataset"]').click();
cy.get('.antd5-modal-content').within(() => { cy.get('.ant-modal-content').within(() => {
cy.get('[data-test="collection-tab-Metrics"]') cy.get('[data-test="collection-tab-Metrics"]')
.contains('Metrics') .contains('Metrics')
.click(); .click();
@@ -78,7 +78,7 @@ describe('Datasource control', () => {
.find('[data-test="crud-delete-icon"]') .find('[data-test="crud-delete-icon"]')
.click(); .click();
cy.get('[data-test="datasource-modal-save"]').click(); cy.get('[data-test="datasource-modal-save"]').click();
cy.get('.antd5-modal-confirm-btns button').contains('OK').click(); cy.get('.ant-modal-confirm-btns button').contains('OK').click();
cy.get('[data-test="metrics"]').contains(newMetricName).should('not.exist'); cy.get('[data-test="metrics"]').contains(newMetricName).should('not.exist');
}); });
}); });
@@ -121,7 +121,7 @@ describe('VizType control', () => {
cy.contains('View all charts').click(); cy.contains('View all charts').click();
cy.get('.antd5-modal-content').within(() => { cy.get('.ant-modal-content').within(() => {
cy.get('button').contains('KPI').click(); // change categories cy.get('button').contains('KPI').click(); // change categories
cy.get('[role="button"]').contains('Big Number').click(); cy.get('[role="button"]').contains('Big Number').click();
cy.get('button').contains('Select').click(); cy.get('button').contains('Select').click();
@@ -42,8 +42,8 @@ describe('Test explore links', () => {
cy.wait('@chartData').then(() => { cy.wait('@chartData').then(() => {
cy.get('code'); cy.get('code');
}); });
cy.get('.antd5-modal-content').within(() => { cy.get('.ant-modal-content').within(() => {
cy.get('button.antd5-modal-close').first().click({ force: true }); cy.get('button.ant-modal-close').first().click({ force: true });
}); });
}); });
@@ -97,8 +97,8 @@ export const databasesPage = {
infoAlert: '.antd5-alert', infoAlert: '.antd5-alert',
serviceAccountInput: '[name="credentials_info"]', serviceAccountInput: '[name="credentials_info"]',
connectionStep: { connectionStep: {
modal: '.antd5-modal-content', modal: '.ant-modal-content',
modalBody: '.antd5-modal-body', modalBody: '.ant-modal-body',
stepTitle: '.css-7x6kk > h4', stepTitle: '.css-7x6kk > h4',
helperBottom: '.helper-bottom', helperBottom: '.helper-bottom',
postgresDatabase: '[name="database"]', postgresDatabase: '[name="database"]',
@@ -150,7 +150,7 @@ export const sqlLabView = {
sqlEditor: '#brace-editor textarea', sqlEditor: '#brace-editor textarea',
saveAsButton: '.SaveQuery > .ant-btn', saveAsButton: '.SaveQuery > .ant-btn',
saveAsModal: { saveAsModal: {
footer: '.antd5-modal-footer', footer: '.ant-modal-footer',
queryNameInput: 'input[class^="ant-input"]', queryNameInput: 'input[class^="ant-input"]',
}, },
sqlToolbar: { sqlToolbar: {
@@ -199,12 +199,12 @@ export const annotationLayersView = {
}, },
modal: { modal: {
content: { content: {
content: '.antd5-modal-body', content: '.ant-modal-body',
title: '.antd5-modal-body > :nth-child(2) > input', title: '.ant-modal-body > :nth-child(2) > input',
description: "[name='descr']", description: "[name='descr']",
}, },
footer: { footer: {
footer: '.antd5-modal-footer', footer: '.ant-modal-footer',
addButton: dataTestLocator('modal-confirm-button'), addButton: dataTestLocator('modal-confirm-button'),
cancelButton: dataTestLocator('modal-cancel-button'), cancelButton: dataTestLocator('modal-cancel-button'),
}, },
@@ -216,7 +216,7 @@ export const datasetsList = {
newDatasetModal: { newDatasetModal: {
inputField: '[class="section"]', inputField: '[class="section"]',
addButton: dataTestLocator('modal-confirm-button'), addButton: dataTestLocator('modal-confirm-button'),
body: '.antd5-modal-body', body: '.ant-modal-body',
}, },
table: { table: {
tableRow: { tableRow: {
@@ -261,7 +261,7 @@ export const datasetsList = {
}, },
}, },
deleteDatasetModal: { deleteDatasetModal: {
modal: '.antd5-modal-content', modal: '.ant-modal-content',
deleteInput: dataTestLocator('delete-modal-input'), deleteInput: dataTestLocator('delete-modal-input'),
deleteButton: dataTestLocator('modal-confirm-button'), deleteButton: dataTestLocator('modal-confirm-button'),
text: '.css-kxmt87', text: '.css-kxmt87',
@@ -318,8 +318,8 @@ export const chartListView = {
}; };
export const nativeFilters = { export const nativeFilters = {
modal: { modal: {
container: '.antd5-modal', container: '.ant-modal',
footer: '.antd5-modal-footer', footer: '.ant-modal-footer',
saveButton: dataTestLocator('native-filter-modal-save-button'), saveButton: dataTestLocator('native-filter-modal-save-button'),
cancelButton: dataTestLocator('native-filter-modal-cancel-button'), cancelButton: dataTestLocator('native-filter-modal-cancel-button'),
confirmCancelButton: dataTestLocator( confirmCancelButton: dataTestLocator(
@@ -476,15 +476,15 @@ export const exploreView = {
}, },
chartAreaItem: '.nv-legend-text', chartAreaItem: '.nv-legend-text',
viewQueryModal: { viewQueryModal: {
container: '.antd5-modal-content', container: '.ant-modal-content',
closeButton: 'button.antd5-modal-close', closeButton: 'button.ant-modal-close',
}, },
embedCodeModal: { embedCodeModal: {
container: dataTestLocator('embed-code-popover'), container: dataTestLocator('embed-code-popover'),
textfield: dataTestLocator('embed-code-textarea'), textfield: dataTestLocator('embed-code-textarea'),
}, },
saveModal: { saveModal: {
modal: '.antd5-modal-content', modal: '.ant-modal-content',
chartNameInput: dataTestLocator('new-chart-name'), chartNameInput: dataTestLocator('new-chart-name'),
dashboardNameInput: '.ant-select-selection-search-input', dashboardNameInput: '.ant-select-selection-search-input',
addToDashboardInput: dataTestLocator( addToDashboardInput: dataTestLocator(
@@ -580,7 +580,7 @@ export const exploreView = {
}, },
}, },
editDatasetModal: { editDatasetModal: {
container: '.antd5-modal-content', container: '.ant-modal-content',
datasetTabsContainer: dataTestLocator('edit-dataset-tabs'), datasetTabsContainer: dataTestLocator('edit-dataset-tabs'),
saveButton: dataTestLocator('datasource-modal-save'), saveButton: dataTestLocator('datasource-modal-save'),
metricsTab: { metricsTab: {
@@ -588,7 +588,7 @@ export const exploreView = {
rowsContainer: dataTestLocator('table-content-rows'), rowsContainer: dataTestLocator('table-content-rows'),
}, },
confirmModal: { confirmModal: {
okButton: '.antd5-modal-confirm-btns .ant-btn-primary', okButton: '.ant-modal-confirm-btns .ant-btn-primary',
}, },
}, },
visualizationTypeModal: { visualizationTypeModal: {
@@ -619,12 +619,12 @@ export const dashboardView = {
closeButton: dataTestLocator('close-button'), closeButton: dataTestLocator('close-button'),
}, },
saveModal: { saveModal: {
modal: '.antd5-modal-content', modal: '.ant-modal-content',
dashboardNameInput: '.ant-input', dashboardNameInput: '.ant-input',
saveButton: dataTestLocator('modal-save-dashboard-button'), saveButton: dataTestLocator('modal-save-dashboard-button'),
}, },
dashboardProperties: { dashboardProperties: {
modal: '.antd5-modal-content', modal: '.ant-modal-content',
dashboardTitleInput: dataTestLocator('dashboard-title-input'), dashboardTitleInput: dataTestLocator('dashboard-title-input'),
modalButton: '[type="button"]', modalButton: '[type="button"]',
}, },
+14 -238
View File
@@ -221,7 +221,6 @@
"babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-dynamic-import-node": "^2.3.3",
"babel-plugin-jsx-remove-data-test-id": "^3.0.0", "babel-plugin-jsx-remove-data-test-id": "^3.0.0",
"babel-plugin-lodash": "^3.3.4", "babel-plugin-lodash": "^3.3.4",
"compression-webpack-plugin": "^11.1.0",
"copy-webpack-plugin": "^12.0.2", "copy-webpack-plugin": "^12.0.2",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"css-loader": "^6.8.1", "css-loader": "^6.8.1",
@@ -284,7 +283,6 @@
"speed-measure-webpack-plugin": "^1.5.0", "speed-measure-webpack-plugin": "^1.5.0",
"storybook": "8.1.11", "storybook": "8.1.11",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"terser-webpack-plugin": "^5.3.11",
"thread-loader": "^4.0.2", "thread-loader": "^4.0.2",
"ts-loader": "^9.5.1", "ts-loader": "^9.5.1",
"typescript": "^4.8.4", "typescript": "^4.8.4",
@@ -19747,79 +19745,6 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"node_modules/compression-webpack-plugin": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-11.1.0.tgz",
"integrity": "sha512-zDOQYp10+upzLxW+VRSjEpRRwBXJdsb5lBMlRxx1g8hckIFBpe3DTI0en2w7h+beuq89576RVzfiXrkdPGrHhA==",
"dev": true,
"dependencies": {
"schema-utils": "^4.2.0",
"serialize-javascript": "^6.0.2"
},
"engines": {
"node": ">= 18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"webpack": "^5.1.0"
}
},
"node_modules/compression-webpack-plugin/node_modules/ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/compression-webpack-plugin/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
"peerDependencies": {
"ajv": "^8.8.2"
}
},
"node_modules/compression-webpack-plugin/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"node_modules/compression-webpack-plugin/node_modules/schema-utils": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
"integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.9.0",
"ajv-formats": "^2.1.1",
"ajv-keywords": "^5.1.0"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/compute-gcd": { "node_modules/compute-gcd": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz",
@@ -51131,9 +51056,8 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "5.37.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", "license": "BSD-2-Clause",
"integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==",
"dependencies": { "dependencies": {
"@jridgewell/source-map": "^0.3.3", "@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2", "acorn": "^8.8.2",
@@ -51148,16 +51072,15 @@
} }
}, },
"node_modules/terser-webpack-plugin": { "node_modules/terser-webpack-plugin": {
"version": "5.3.11", "version": "5.3.10",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz",
"integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==",
"devOptional": true, "devOptional": true,
"license": "MIT",
"dependencies": { "dependencies": {
"@jridgewell/trace-mapping": "^0.3.25", "@jridgewell/trace-mapping": "^0.3.20",
"jest-worker": "^27.4.5", "jest-worker": "^27.4.5",
"schema-utils": "^4.3.0", "schema-utils": "^3.1.1",
"serialize-javascript": "^6.0.2", "serialize-javascript": "^6.0.1",
"terser": "^5.31.1" "terser": "^5.26.0"
}, },
"engines": { "engines": {
"node": ">= 10.13.0" "node": ">= 10.13.0"
@@ -51181,34 +51104,6 @@
} }
} }
}, },
"node_modules/terser-webpack-plugin/node_modules/ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"devOptional": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"devOptional": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
"peerDependencies": {
"ajv": "^8.8.2"
}
},
"node_modules/terser-webpack-plugin/node_modules/has-flag": { "node_modules/terser-webpack-plugin/node_modules/has-flag": {
"version": "4.0.0", "version": "4.0.0",
"devOptional": true, "devOptional": true,
@@ -51230,31 +51125,6 @@
"node": ">= 10.13.0" "node": ">= 10.13.0"
} }
}, },
"node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"devOptional": true
},
"node_modules/terser-webpack-plugin/node_modules/schema-utils": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
"integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
"devOptional": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.9.0",
"ajv-formats": "^2.1.1",
"ajv-keywords": "^5.1.0"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/terser-webpack-plugin/node_modules/supports-color": { "node_modules/terser-webpack-plugin/node_modules/supports-color": {
"version": "8.1.1", "version": "8.1.1",
"devOptional": true, "devOptional": true,
@@ -73618,57 +73488,6 @@
"vary": "~1.1.2" "vary": "~1.1.2"
} }
}, },
"compression-webpack-plugin": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-11.1.0.tgz",
"integrity": "sha512-zDOQYp10+upzLxW+VRSjEpRRwBXJdsb5lBMlRxx1g8hckIFBpe3DTI0en2w7h+beuq89576RVzfiXrkdPGrHhA==",
"dev": true,
"requires": {
"schema-utils": "^4.2.0",
"serialize-javascript": "^6.0.2"
},
"dependencies": {
"ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
}
},
"ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.3"
}
},
"json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"schema-utils": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
"integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.9.0",
"ajv-formats": "^2.1.1",
"ajv-keywords": "^5.1.0"
}
}
}
},
"compute-gcd": { "compute-gcd": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz", "resolved": "https://registry.npmjs.org/compute-gcd/-/compute-gcd-1.2.1.tgz",
@@ -93486,9 +93305,7 @@
"dev": true "dev": true
}, },
"terser": { "terser": {
"version": "5.37.0", "version": "5.27.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz",
"integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==",
"requires": { "requires": {
"@jridgewell/source-map": "^0.3.3", "@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2", "acorn": "^8.8.2",
@@ -93497,39 +93314,16 @@
} }
}, },
"terser-webpack-plugin": { "terser-webpack-plugin": {
"version": "5.3.11", "version": "5.3.10",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz",
"integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==",
"devOptional": true, "devOptional": true,
"requires": { "requires": {
"@jridgewell/trace-mapping": "^0.3.25", "@jridgewell/trace-mapping": "^0.3.20",
"jest-worker": "^27.4.5", "jest-worker": "^27.4.5",
"schema-utils": "^4.3.0", "schema-utils": "^3.1.1",
"serialize-javascript": "^6.0.2", "serialize-javascript": "^6.0.1",
"terser": "^5.31.1" "terser": "^5.26.0"
}, },
"dependencies": { "dependencies": {
"ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"devOptional": true,
"requires": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
}
},
"ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"devOptional": true,
"requires": {
"fast-deep-equal": "^3.1.3"
}
},
"has-flag": { "has-flag": {
"version": "4.0.0", "version": "4.0.0",
"devOptional": true "devOptional": true
@@ -93543,24 +93337,6 @@
"supports-color": "^8.0.0" "supports-color": "^8.0.0"
} }
}, },
"json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"devOptional": true
},
"schema-utils": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
"integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
"devOptional": true,
"requires": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.9.0",
"ajv-formats": "^2.1.1",
"ajv-keywords": "^5.1.0"
}
},
"supports-color": { "supports-color": {
"version": "8.1.1", "version": "8.1.1",
"devOptional": true, "devOptional": true,
-2
View File
@@ -288,7 +288,6 @@
"babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-dynamic-import-node": "^2.3.3",
"babel-plugin-jsx-remove-data-test-id": "^3.0.0", "babel-plugin-jsx-remove-data-test-id": "^3.0.0",
"babel-plugin-lodash": "^3.3.4", "babel-plugin-lodash": "^3.3.4",
"compression-webpack-plugin": "^11.1.0",
"copy-webpack-plugin": "^12.0.2", "copy-webpack-plugin": "^12.0.2",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"css-loader": "^6.8.1", "css-loader": "^6.8.1",
@@ -351,7 +350,6 @@
"speed-measure-webpack-plugin": "^1.5.0", "speed-measure-webpack-plugin": "^1.5.0",
"storybook": "8.1.11", "storybook": "8.1.11",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"terser-webpack-plugin": "^5.3.11",
"thread-loader": "^4.0.2", "thread-loader": "^4.0.2",
"ts-loader": "^9.5.1", "ts-loader": "^9.5.1",
"typescript": "^4.8.4", "typescript": "^4.8.4",
File diff suppressed because one or more lines are too long
@@ -80,7 +80,6 @@ import ethiopia from './countries/ethiopia.geojson';
import fiji from './countries/fiji.geojson'; import fiji from './countries/fiji.geojson';
import finland from './countries/finland.geojson'; import finland from './countries/finland.geojson';
import france from './countries/france.geojson'; import france from './countries/france.geojson';
import france_overseas from './countries/france_overseas.geojson';
import france_regions from './countries/france_regions.geojson'; import france_regions from './countries/france_regions.geojson';
import french_polynesia from './countries/french_polynesia.geojson'; import french_polynesia from './countries/french_polynesia.geojson';
import gabon from './countries/gabon.geojson'; import gabon from './countries/gabon.geojson';
@@ -281,7 +280,6 @@ export const countries = {
fiji, fiji,
finland, finland,
france, france,
france_overseas,
france_regions, france_regions,
french_polynesia, french_polynesia,
gabon, gabon,
@@ -429,9 +427,6 @@ export const countryOptions = Object.keys(countries).map(x => {
if (x === 'france_regions') { if (x === 'france_regions') {
return [x, 'France (regions)']; return [x, 'France (regions)'];
} }
if (x === 'france_overseas') {
return [x, 'France (with overseas)'];
}
if (x === 'turkey_regions') { if (x === 'turkey_regions') {
return [x, 'Turkey (regions)']; return [x, 'Turkey (regions)'];
} }
File diff suppressed because one or more lines are too long
@@ -188,11 +188,7 @@ export default function transformProps(
showTotal, showTotal,
sliceId, sliceId,
} = formData; } = formData;
const { const { currencyFormats = {}, columnFormats = {} } = datasource;
currencyFormats = {},
columnFormats = {},
verboseMap = {},
} = datasource;
const refs: Refs = {}; const refs: Refs = {};
const primaryValueFormatter = getValueFormatter( const primaryValueFormatter = getValueFormatter(
metric, metric,
@@ -338,10 +334,8 @@ export default function transformProps(
secondaryValueFormatter, secondaryValueFormatter,
colorByCategory, colorByCategory,
totalValue, totalValue,
metricLabel: verboseMap[metricLabel] || metricLabel, metricLabel,
secondaryMetricLabel: secondaryMetricLabel secondaryMetricLabel,
? verboseMap[secondaryMetricLabel] || secondaryMetricLabel
: undefined,
}), }),
}, },
series: [ series: [
+26 -29
View File
@@ -39,37 +39,34 @@ export const GlobalStyles = () => (
.echarts-tooltip[style*='visibility: hidden'] { .echarts-tooltip[style*='visibility: hidden'] {
display: none !important; display: none !important;
} }
.antd5-dropdown, // TODO: Remove when on Ant Design 5.
.ant-dropdown {
z-index: ${theme.zIndex.max};
}
// TODO: Remove when buttons have been upgraded to Ant Design 5.
// Check src/components/Modal for more info. // Check src/components/Modal for more info.
.ant-modal-confirm { .modal-functions-ok-button {
button { border-radius: ${theme.borderRadius}px;
border: none; background: ${theme.colors.primary.base};
border-radius: ${theme.borderRadius}px; border: none;
line-height: 1.5715; color: ${theme.colors.grayscale.light5};
font-size: ${theme.typography.sizes.s}px; line-height: 1.5715;
font-weight: ${theme.typography.weights.bold}; font-size: ${theme.typography.sizes.s}px;
font-weight: ${theme.typography.weights.bold};
&:hover {
background: ${theme.colors.primary.dark1};
} }
.ant-btn-primary:not(.btn-danger) { }
background: ${theme.colors.primary.base}; .modal-functions-cancel-button {
color: ${theme.colors.grayscale.light5}; border-radius: ${theme.borderRadius}px;
&:hover { background: ${theme.colors.primary.light4};
background: ${theme.colors.primary.dark1}; border: none;
} color: ${theme.colors.primary.dark1};
} line-height: 1.5715;
.ant-btn-default:not(.btn-danger) { font-size: ${theme.typography.sizes.s}px;
background: ${theme.colors.primary.light4}; font-weight: ${theme.typography.weights.bold};
color: ${theme.colors.primary.dark1}; &:hover {
&:hover { background: ${mix(
background: ${mix( 0.1,
0.1, theme.colors.primary.base,
theme.colors.primary.base, theme.colors.primary.light4,
theme.colors.primary.light4, )};
)};
}
} }
} }
.column-config-popover { .column-config-popover {
@@ -89,11 +89,11 @@ const SqlLabStyles = styled.div`
} }
} }
.ResultsModal .antd5-modal-body { .ResultsModal .ant-modal-body {
min-height: ${theme.gridUnit * 140}px; min-height: ${theme.gridUnit * 140}px;
} }
.antd5-modal-body { .ant-modal-body {
overflow: auto; overflow: auto;
} }
} }
@@ -73,10 +73,10 @@ describe('SaveDatasetModal', () => {
const inputField = screen.getByRole('textbox'); const inputField = screen.getByRole('textbox');
const inputFieldText = screen.getByDisplayValue(/unimportant/i); const inputFieldText = screen.getByDisplayValue(/unimportant/i);
expect(saveRadioBtn).toBeInTheDocument(); expect(saveRadioBtn).toBeVisible();
expect(fieldLabel).toBeInTheDocument(); expect(fieldLabel).toBeVisible();
expect(inputField).toBeInTheDocument(); expect(inputField).toBeVisible();
expect(inputFieldText).toBeInTheDocument(); expect(inputFieldText).toBeVisible();
}); });
it('renders an "Overwrite existing" field', () => { it('renders an "Overwrite existing" field', () => {
@@ -89,23 +89,23 @@ describe('SaveDatasetModal', () => {
const inputField = screen.getByRole('combobox'); const inputField = screen.getByRole('combobox');
const placeholderText = screen.getByText(/select or type dataset name/i); const placeholderText = screen.getByText(/select or type dataset name/i);
expect(overwriteRadioBtn).toBeInTheDocument(); expect(overwriteRadioBtn).toBeVisible();
expect(fieldLabel).toBeInTheDocument(); expect(fieldLabel).toBeVisible();
expect(inputField).toBeInTheDocument(); expect(inputField).toBeVisible();
expect(placeholderText).toBeInTheDocument(); expect(placeholderText).toBeVisible();
}); });
it('renders a close button', () => { it('renders a close button', () => {
render(<SaveDatasetModal {...mockedProps} />, { useRedux: true }); render(<SaveDatasetModal {...mockedProps} />, { useRedux: true });
expect(screen.getByRole('button', { name: /close/i })).toBeInTheDocument(); expect(screen.getByRole('button', { name: /close/i })).toBeVisible();
}); });
it('renders a save button when "Save as new" is selected', () => { it('renders a save button when "Save as new" is selected', () => {
render(<SaveDatasetModal {...mockedProps} />, { useRedux: true }); render(<SaveDatasetModal {...mockedProps} />, { useRedux: true });
// "Save as new" is selected when the modal opens by default // "Save as new" is selected when the modal opens by default
expect(screen.getByRole('button', { name: /save/i })).toBeInTheDocument(); expect(screen.getByRole('button', { name: /save/i })).toBeVisible();
}); });
it('renders an overwrite button when "Overwrite existing" is selected', () => { it('renders an overwrite button when "Overwrite existing" is selected', () => {
@@ -117,9 +117,7 @@ describe('SaveDatasetModal', () => {
}); });
userEvent.click(overwriteRadioBtn); userEvent.click(overwriteRadioBtn);
expect( expect(screen.getByRole('button', { name: /overwrite/i })).toBeVisible();
screen.getByRole('button', { name: /overwrite/i }),
).toBeInTheDocument();
}); });
it('renders the overwrite button as disabled until an existing dataset is selected', async () => { it('renders the overwrite button as disabled until an existing dataset is selected', async () => {
@@ -183,16 +181,14 @@ describe('SaveDatasetModal', () => {
userEvent.click(overwriteConfirmationBtn); userEvent.click(overwriteConfirmationBtn);
// Overwrite screen text // Overwrite screen text
expect(screen.getByText(/save or overwrite dataset/i)).toBeInTheDocument(); expect(screen.getByText(/save or overwrite dataset/i)).toBeVisible();
expect( expect(
screen.getByText(/are you sure you want to overwrite this dataset\?/i), screen.getByText(/are you sure you want to overwrite this dataset\?/i),
).toBeInTheDocument(); ).toBeVisible();
// Overwrite screen buttons // Overwrite screen buttons
expect(screen.getByRole('button', { name: /close/i })).toBeInTheDocument(); expect(screen.getByRole('button', { name: /close/i })).toBeVisible();
expect(screen.getByRole('button', { name: /back/i })).toBeInTheDocument(); expect(screen.getByRole('button', { name: /back/i })).toBeVisible();
expect( expect(screen.getByRole('button', { name: /overwrite/i })).toBeVisible();
screen.getByRole('button', { name: /overwrite/i }),
).toBeInTheDocument();
}); });
it('sends the schema when creating the dataset', async () => { it('sends the schema when creating the dataset', async () => {
@@ -104,7 +104,7 @@ describe('SavedQuery', () => {
name: /save query/i, name: /save query/i,
}); });
expect(saveQueryModalHeader).toBeInTheDocument(); expect(saveQueryModalHeader).toBeVisible();
}); });
it('renders the save query modal UI', () => { it('renders the save query modal UI', () => {
@@ -129,17 +129,17 @@ describe('SavedQuery', () => {
const saveBtns = screen.getAllByRole('button', { name: /save/i }); const saveBtns = screen.getAllByRole('button', { name: /save/i });
const cancelBtn = screen.getByRole('button', { name: /cancel/i }); const cancelBtn = screen.getByRole('button', { name: /cancel/i });
expect(closeBtn).toBeInTheDocument(); expect(closeBtn).toBeVisible();
expect(saveQueryModalHeader).toBeInTheDocument(); expect(saveQueryModalHeader).toBeVisible();
expect(nameLabel).toBeInTheDocument(); expect(nameLabel).toBeVisible();
expect(descriptionLabel).toBeInTheDocument(); expect(descriptionLabel).toBeVisible();
expect(textBoxes.length).toBe(2); expect(textBoxes.length).toBe(2);
expect(nameTextbox).toBeInTheDocument(); expect(nameTextbox).toBeVisible();
expect(descriptionTextbox).toBeInTheDocument(); expect(descriptionTextbox).toBeVisible();
expect(saveBtns.length).toBe(2); expect(saveBtns.length).toBe(2);
expect(saveBtns[0]).toBeInTheDocument(); expect(saveBtns[0]).toBeVisible();
expect(saveBtns[1]).toBeInTheDocument(); expect(saveBtns[1]).toBeVisible();
expect(cancelBtn).toBeInTheDocument(); expect(cancelBtn).toBeVisible();
}); });
it('renders a "save as new" and "update" button if query already exists', () => { it('renders a "save as new" and "update" button if query already exists', () => {
@@ -163,8 +163,8 @@ describe('SavedQuery', () => {
const saveAsNewBtn = screen.getByRole('button', { name: /save as new/i }); const saveAsNewBtn = screen.getByRole('button', { name: /save as new/i });
const updateBtn = screen.getByRole('button', { name: /update/i }); const updateBtn = screen.getByRole('button', { name: /update/i });
expect(saveAsNewBtn).toBeInTheDocument(); expect(saveAsNewBtn).toBeVisible();
expect(updateBtn).toBeInTheDocument(); expect(updateBtn).toBeVisible();
}); });
it('renders a split save button when allows_virtual_table_explore is enabled', async () => { it('renders a split save button when allows_virtual_table_explore is enabled', async () => {
@@ -188,15 +188,17 @@ describe('SavedQuery', () => {
store: mockStore(mockState), store: mockStore(mockState),
}); });
const caretBtn = await screen.findByRole('button', { name: /caret-down/i }); await waitFor(() => {
userEvent.click(caretBtn); const caretBtn = screen.getByRole('button', { name: /caret-down/i });
userEvent.click(caretBtn);
const saveDatasetMenuItem = await screen.findByText(/save dataset/i); const saveDatasetMenuItem = screen.getByText(/save dataset/i);
userEvent.click(saveDatasetMenuItem); userEvent.click(saveDatasetMenuItem);
});
const saveDatasetHeader = screen.getByText(/save or overwrite dataset/i); const saveDatasetHeader = screen.getByText(/save or overwrite dataset/i);
expect(saveDatasetHeader).toBeInTheDocument(); expect(saveDatasetHeader).toBeVisible();
}); });
it('renders the save dataset modal UI', async () => { it('renders the save dataset modal UI', async () => {
@@ -205,11 +207,13 @@ describe('SavedQuery', () => {
store: mockStore(mockState), store: mockStore(mockState),
}); });
const caretBtn = await screen.findByRole('button', { name: /caret-down/i }); await waitFor(() => {
userEvent.click(caretBtn); const caretBtn = screen.getByRole('button', { name: /caret-down/i });
userEvent.click(caretBtn);
const saveDatasetMenuItem = await screen.findByText(/save dataset/i); const saveDatasetMenuItem = screen.getByText(/save dataset/i);
userEvent.click(saveDatasetMenuItem); userEvent.click(saveDatasetMenuItem);
});
const closeBtn = screen.getByRole('button', { name: /close/i }); const closeBtn = screen.getByRole('button', { name: /close/i });
const saveDatasetHeader = screen.getByText(/save or overwrite dataset/i); const saveDatasetHeader = screen.getByText(/save or overwrite dataset/i);
@@ -227,14 +231,14 @@ describe('SavedQuery', () => {
/select or type dataset name/i, /select or type dataset name/i,
); );
expect(saveDatasetHeader).toBeInTheDocument(); expect(saveDatasetHeader).toBeVisible();
expect(closeBtn).toBeInTheDocument(); expect(closeBtn).toBeVisible();
expect(saveRadio).toBeInTheDocument(); expect(saveRadio).toBeVisible();
expect(saveLabel).toBeInTheDocument(); expect(saveLabel).toBeVisible();
expect(saveTextbox).toBeInTheDocument(); expect(saveTextbox).toBeVisible();
expect(overwriteRadio).toBeInTheDocument(); expect(overwriteRadio).toBeVisible();
expect(overwriteLabel).toBeInTheDocument(); expect(overwriteLabel).toBeVisible();
expect(overwriteCombobox).toBeInTheDocument(); expect(overwriteCombobox).toBeVisible();
expect(overwritePlaceholderText).toBeInTheDocument(); expect(overwritePlaceholderText).toBeVisible();
}); });
}); });
@@ -428,7 +428,7 @@ export default function DrillByModal({
return ( return (
<Modal <Modal
css={css` css={css`
.antd5-modal-footer { .ant-modal-footer {
border-top: none; border-top: none;
} }
`} `}
@@ -117,13 +117,12 @@ const expectDrillToDetailModal = async (
filters: BinaryQueryObjectFilterClause[] = [], filters: BinaryQueryObjectFilterClause[] = [],
) => { ) => {
const button = screen.getByRole('menuitem', { name: buttonName }); const button = screen.getByRole('menuitem', { name: buttonName });
userEvent.click(button); userEvent.click(button);
const modal = await screen.findByRole('dialog', { const modal = await screen.findByRole('dialog', {
name: `Drill to detail: ${chartName}`, name: `Drill to detail: ${chartName}`,
}); });
expect(modal).toBeInTheDocument(); expect(modal).toBeVisible();
expect(screen.getByTestId('modal-filters')).toHaveTextContent( expect(screen.getByTestId('modal-filters')).toHaveTextContent(
JSON.stringify(filters), JSON.stringify(filters),
); );
@@ -118,7 +118,7 @@ export default function DrillDetailModal({
show={showModal} show={showModal}
onHide={onHideModal ?? (() => null)} onHide={onHideModal ?? (() => null)}
css={css` css={css`
.antd5-modal-body { .ant-modal-body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@@ -74,8 +74,8 @@ interface ChangeDatasourceModalProps {
show: boolean; show: boolean;
} }
const CustomStyledModal = styled(StyledModal)` const Modal = styled(StyledModal)`
.antd5-modal-body { .ant-modal-body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@@ -255,7 +255,7 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
}; };
return ( return (
<CustomStyledModal <Modal
show={show} show={show}
onHide={onHide} onHide={onHide}
responsive responsive
@@ -323,7 +323,7 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
)} )}
{confirmChange && <>{CONFIRM_WARNING_MESSAGE}</>} {confirmChange && <>{CONFIRM_WARNING_MESSAGE}</>}
</> </>
</CustomStyledModal> </Modal>
); );
}; };
@@ -30,9 +30,9 @@ test('Must display title and content', () => {
}; };
render(<DeleteModal {...props} />); render(<DeleteModal {...props} />);
expect(screen.getByTestId('test-title')).toBeInTheDocument(); expect(screen.getByTestId('test-title')).toBeInTheDocument();
expect(screen.getByTestId('test-title')).toBeInTheDocument(); expect(screen.getByTestId('test-title')).toBeVisible();
expect(screen.getByTestId('test-description')).toBeInTheDocument();
expect(screen.getByTestId('test-description')).toBeInTheDocument(); expect(screen.getByTestId('test-description')).toBeInTheDocument();
expect(screen.getByTestId('test-description')).toBeVisible();
}); });
test('Calling "onHide"', () => { test('Calling "onHide"', () => {
@@ -53,7 +53,7 @@ test('Calling "onHide"', () => {
expect(screen.getByTestId('delete-modal-input')).toHaveValue('del'); expect(screen.getByTestId('delete-modal-input')).toHaveValue('del');
// close the modal // close the modal
expect(screen.getByText('×')).toBeInTheDocument(); expect(screen.getByText('×')).toBeVisible();
userEvent.click(screen.getByText('×')); userEvent.click(screen.getByText('×'));
expect(props.onHide).toHaveBeenCalledTimes(1); expect(props.onHide).toHaveBeenCalledTimes(1);
expect(props.onConfirm).toHaveBeenCalledTimes(0); expect(props.onConfirm).toHaveBeenCalledTimes(0);
@@ -73,7 +73,7 @@ test('Calling "onConfirm" only after typing "delete" in the input', () => {
render(<DeleteModal {...props} />); render(<DeleteModal {...props} />);
expect(props.onHide).toHaveBeenCalledTimes(0); expect(props.onHide).toHaveBeenCalledTimes(0);
expect(props.onConfirm).toHaveBeenCalledTimes(0); expect(props.onConfirm).toHaveBeenCalledTimes(0);
expect(screen.getByTestId('delete-modal-input')).toBeInTheDocument(); expect(screen.getByTestId('delete-modal-input')).toBeVisible();
expect(props.onConfirm).toHaveBeenCalledTimes(0); expect(props.onConfirm).toHaveBeenCalledTimes(0);
// do not execute "onConfirm" if you have not typed "delete" // do not execute "onConfirm" if you have not typed "delete"
@@ -90,9 +90,8 @@ const StyleMenuItem = styled(Menu.Item)<{ divider?: boolean }>`
const StyleSubmenuItem = styled.div` const StyleSubmenuItem = styled.div`
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
width: 100%; > span {
> div { width: 100%;
flex-grow: 1;
} }
`; `;
@@ -103,7 +102,7 @@ export default (props: DropDownSelectableProps) => {
() => (label: string | ReactNode, key: string, divider?: boolean) => ( () => (label: string | ReactNode, key: string, divider?: boolean) => (
<StyleMenuItem key={key} divider={divider}> <StyleMenuItem key={key} divider={divider}>
<StyleSubmenuItem> <StyleSubmenuItem>
{label} <span>{label}</span>
{selectedKeys?.includes(key) && ( {selectedKeys?.includes(key) && (
<Icons.Check <Icons.Check
iconColor={theme.colors.primary.base} iconColor={theme.colors.primary.base}
@@ -70,7 +70,7 @@ const ErrorModal = styled(Modal)<{ level: ErrorLevel }>`
color: ${({ level, theme }) => theme.colors[level].dark2}; color: ${({ level, theme }) => theme.colors[level].dark2};
overflow-wrap: break-word; overflow-wrap: break-word;
.antd5-modal-header { .ant-modal-header {
background-color: ${({ level, theme }) => theme.colors[level].light2}; background-color: ${({ level, theme }) => theme.colors[level].light2};
padding: ${({ theme }) => 4 * theme.gridUnit}px; padding: ${({ theme }) => 4 * theme.gridUnit}px;
} }
@@ -16,8 +16,8 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { ModalFuncProps } from 'antd/lib/modal';
import Modal, { ModalProps, ModalFuncProps } from '.'; import Modal, { ModalProps } from '.';
import Button from '../Button'; import Button from '../Button';
export default { export default {
@@ -37,7 +37,6 @@ InteractiveModal.args = {
title: "I'm a modal!", title: "I'm a modal!",
resizable: false, resizable: false,
draggable: false, draggable: false,
width: 500,
}; };
InteractiveModal.argTypes = { InteractiveModal.argTypes = {
@@ -56,8 +55,4 @@ export const ModalFunctions = (props: ModalFuncProps) => (
ModalFunctions.args = { ModalFunctions.args = {
title: 'Modal title', title: 'Modal title',
content: 'Modal content', content: 'Modal content',
keyboard: true,
okText: 'Test',
maskClosable: true,
mask: true,
}; };
@@ -26,13 +26,10 @@ import {
useState, useState,
} from 'react'; } from 'react';
import { isNil } from 'lodash'; import { isNil } from 'lodash';
import { ModalFuncProps } from 'antd/lib/modal';
import { styled, t } from '@superset-ui/core'; import { styled, t } from '@superset-ui/core';
import { css } from '@emotion/react'; import { css } from '@emotion/react';
import { import { AntdModal, AntdModalProps } from 'src/components';
Modal as AntdModal,
ModalProps as AntdModalProps,
ModalFuncProps,
} from 'antd-v5';
import Button from 'src/components/Button'; import Button from 'src/components/Button';
import { Resizable, ResizableProps } from 're-resizable'; import { Resizable, ResizableProps } from 're-resizable';
import Draggable, { import Draggable, {
@@ -83,8 +80,6 @@ interface StyledModalProps {
resizable?: boolean; resizable?: boolean;
} }
export type { ModalFuncProps };
const MODAL_HEADER_HEIGHT = 55; const MODAL_HEADER_HEIGHT = 55;
const MODAL_MIN_CONTENT_HEIGHT = 54; const MODAL_MIN_CONTENT_HEIGHT = 54;
const MODAL_FOOTER_HEIGHT = 65; const MODAL_FOOTER_HEIGHT = 65;
@@ -94,7 +89,7 @@ const RESIZABLE_MIN_WIDTH = '380px';
const RESIZABLE_MAX_HEIGHT = '100vh'; const RESIZABLE_MAX_HEIGHT = '100vh';
const RESIZABLE_MAX_WIDTH = '100vw'; const RESIZABLE_MAX_WIDTH = '100vw';
export const BaseModal = (props: AntdModalProps) => ( const BaseModal = (props: AntdModalProps) => (
// Removes mask animation. Fixed in 4.6.0. // Removes mask animation. Fixed in 4.6.0.
// https://github.com/ant-design/ant-design/issues/27192 // https://github.com/ant-design/ant-design/issues/27192
<AntdModal {...props} maskTransitionName="" /> <AntdModal {...props} maskTransitionName="" />
@@ -111,45 +106,30 @@ export const StyledModal = styled(BaseModal)<StyledModalProps>`
top: 0; top: 0;
`} `}
.antd5-modal-content { .ant-modal-content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
max-height: ${({ theme }) => `calc(100vh - ${theme.gridUnit * 8}px)`}; max-height: ${({ theme }) => `calc(100vh - ${theme.gridUnit * 8}px)`};
margin-bottom: ${({ theme }) => theme.gridUnit * 4}px; margin-bottom: ${({ theme }) => theme.gridUnit * 4}px;
margin-top: ${({ theme }) => theme.gridUnit * 4}px; margin-top: ${({ theme }) => theme.gridUnit * 4}px;
padding: 0;
} }
.antd5-modal-header { .ant-modal-header {
flex: 0 0 auto; flex: 0 0 auto;
background-color: ${({ theme }) => theme.colors.grayscale.light4};
border-radius: ${({ theme }) => theme.borderRadius}px border-radius: ${({ theme }) => theme.borderRadius}px
${({ theme }) => theme.borderRadius}px 0 0; ${({ theme }) => theme.borderRadius}px 0 0;
padding: ${({ theme }) => theme.gridUnit * 4}px padding-left: ${({ theme }) => theme.gridUnit * 4}px;
${({ theme }) => theme.gridUnit * 6}px; padding-right: ${({ theme }) => theme.gridUnit * 4}px;
.antd5-modal-title { .ant-modal-title h4 {
font-weight: ${({ theme }) => theme.typography.weights.medium};
}
.antd5-modal-title h4 {
display: flex; display: flex;
margin: 0; margin: 0;
align-items: center; align-items: center;
} }
} }
.antd5-modal-close { .ant-modal-close-x {
width: ${({ theme }) => theme.gridUnit * 14}px;
height: ${({ theme }) => theme.gridUnit * 14}px;
top: 0;
right: 0;
}
.antd5-modal-close:hover {
background: transparent;
}
.antd5-modal-close-x {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -162,18 +142,17 @@ export const StyledModal = styled(BaseModal)<StyledModalProps>`
} }
} }
.antd5-modal-body { .ant-modal-body {
flex: 0 1 auto; flex: 0 1 auto;
padding: ${({ theme }) => theme.gridUnit * 4}px; padding: ${({ theme }) => theme.gridUnit * 4}px;
overflow: auto; overflow: auto;
${({ resizable, height }) => !resizable && height && `height: ${height};`} ${({ resizable, height }) => !resizable && height && `height: ${height};`}
} }
.antd5-modal-footer { .ant-modal-footer {
flex: 0 0 1; flex: 0 0 1;
border-top: ${({ theme }) => theme.gridUnit / 4}px solid border-top: ${({ theme }) => theme.gridUnit / 4}px solid
${({ theme }) => theme.colors.grayscale.light2}; ${({ theme }) => theme.colors.grayscale.light2};
padding: ${({ theme }) => theme.gridUnit * 4}px; padding: ${({ theme }) => theme.gridUnit * 4}px;
margin-top: 0;
.btn { .btn {
font-size: 12px; font-size: 12px;
@@ -191,14 +170,14 @@ export const StyledModal = styled(BaseModal)<StyledModalProps>`
margin-top: -${({ theme }) => theme.gridUnit * 4}px; margin-top: -${({ theme }) => theme.gridUnit * 4}px;
} }
&.no-content-padding .antd5-modal-body { &.no-content-padding .ant-modal-body {
padding: 0; padding: 0;
} }
${({ draggable, theme }) => ${({ draggable, theme }) =>
draggable && draggable &&
` `
.antd5-modal-header { .ant-modal-header {
padding: 0; padding: 0;
.draggable-trigger { .draggable-trigger {
cursor: move; cursor: move;
@@ -218,10 +197,10 @@ export const StyledModal = styled(BaseModal)<StyledModalProps>`
height: 100%; height: 100%;
} }
.antd5-modal-content { .ant-modal-content {
height: 100%; height: 100%;
.antd5-modal-body { .ant-modal-body {
/* 100% - header height - footer height */ /* 100% - header height - footer height */
height: ${ height: ${
hideFooter hideFooter
@@ -233,7 +212,6 @@ export const StyledModal = styled(BaseModal)<StyledModalProps>`
} }
`} `}
`; `;
const defaultResizableConfig = (hideFooter: boolean | undefined) => ({ const defaultResizableConfig = (hideFooter: boolean | undefined) => ({
maxHeight: RESIZABLE_MAX_HEIGHT, maxHeight: RESIZABLE_MAX_HEIGHT,
maxWidth: RESIZABLE_MAX_WIDTH, maxWidth: RESIZABLE_MAX_WIDTH,
@@ -355,7 +333,7 @@ const CustomModal = ({
width={modalWidth} width={modalWidth}
maxWidth={maxWidth} maxWidth={maxWidth}
responsive={responsive} responsive={responsive}
open={show} visible={show}
title={<ModalTitle />} title={<ModalTitle />}
closeIcon={ closeIcon={
<span className="close" aria-hidden="true"> <span className="close" aria-hidden="true">
@@ -399,13 +377,26 @@ const CustomModal = ({
}; };
CustomModal.displayName = 'Modal'; CustomModal.displayName = 'Modal';
// Ant Design 4 does not allow overriding Modal's buttons when
// using one of the pre-defined functions. Ant Design 5 Modal introduced
// the footer property that will allow that. Meanwhile, we're replicating
// Button style using global CSS in src/GlobalStyles.tsx.
// TODO: Replace this logic when on Ant Design 5.
const buttonProps = {
okButtonProps: { className: 'modal-functions-ok-button' },
cancelButtonProps: { className: 'modal-functions-cancel-button' },
};
// TODO: in another PR, rename this to CompatabilityModal // TODO: in another PR, rename this to CompatabilityModal
// and demote it as the default export. // and demote it as the default export.
// We should start using AntD component interfaces going forward. // We should start using AntD component interfaces going forward.
const Modal = Object.assign(CustomModal, { const Modal = Object.assign(CustomModal, {
error: AntdModal.error, error: (config: ModalFuncProps) =>
warning: AntdModal.warning, AntdModal.error({ ...config, ...buttonProps }),
confirm: AntdModal.confirm, warning: (config: ModalFuncProps) =>
AntdModal.warning({ ...config, ...buttonProps }),
confirm: (config: ModalFuncProps) =>
AntdModal.confirm({ ...config, ...buttonProps }),
useModal: AntdModal.useModal, useModal: AntdModal.useModal,
}); });
@@ -62,6 +62,7 @@ export {
Dropdown as AntdDropdown, Dropdown as AntdDropdown,
Form as AntdForm, Form as AntdForm,
Input as AntdInput, Input as AntdInput,
Modal as AntdModal,
Select as AntdSelect, Select as AntdSelect,
Slider as AntdSlider, Slider as AntdSlider,
Tabs as AntdTabs, Tabs as AntdTabs,
@@ -70,5 +71,6 @@ export {
// Exported types // Exported types
export type { FormInstance } from 'antd/lib/form'; export type { FormInstance } from 'antd/lib/form';
export type { ModalProps as AntdModalProps } from 'antd/lib/modal';
export type { DropDownProps as AntdDropdownProps } from 'antd/lib/dropdown'; export type { DropDownProps as AntdDropdownProps } from 'antd/lib/dropdown';
export type { RadioChangeEvent } from 'antd/lib/radio'; export type { RadioChangeEvent } from 'antd/lib/radio';
@@ -302,7 +302,6 @@ const PropertiesModal = ({
content: t('A valid color scheme is required'), content: t('A valid color scheme is required'),
okButtonProps: { danger: true, className: 'btn-danger' }, okButtonProps: { danger: true, className: 'btn-danger' },
}); });
onHide();
throw new Error('A valid color scheme is required'); throw new Error('A valid color scheme is required');
} }
@@ -118,12 +118,10 @@ test('is valid', () => {
test('renders refresh interval modal', async () => { test('renders refresh interval modal', async () => {
render(setup(editModeOnProps)); render(setup(editModeOnProps));
expect(screen.queryByText('Refresh Interval')).not.toBeInTheDocument();
await openRefreshIntervalModal(); await openRefreshIntervalModal();
// Assert that modal exists by checking for the modal title // Assert that modal exists by checking for the modal title
expect(screen.getByText('Refresh interval')).toBeInTheDocument(); expect(screen.getByText('Refresh interval')).toBeVisible();
}); });
test('renders refresh interval options', async () => { test('renders refresh interval options', async () => {

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