mirror of
https://github.com/apache/superset.git
synced 2026-06-13 11:39:16 +00:00
Compare commits
1 Commits
6.0.0rc1
...
supersetbo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3fb775a17 |
@@ -1,20 +0,0 @@
|
||||
# Keep this in sync with the base image in the main Dockerfile (ARG PY_VER)
|
||||
FROM python:3.11.13-bookworm AS base
|
||||
|
||||
# Install system dependencies that Superset needs
|
||||
# This layer will be cached across Codespace sessions
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libsasl2-dev \
|
||||
libldap2-dev \
|
||||
libpq-dev \
|
||||
tmux \
|
||||
gh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install uv for fast Python package management
|
||||
# This will also be cached in the image
|
||||
RUN curl -LsSf https://astral.sh/uv/install.sh | sh && \
|
||||
echo 'export PATH="/root/.cargo/bin:$PATH"' >> /etc/bash.bashrc
|
||||
|
||||
# Set the cargo/bin directory in PATH for all users
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
@@ -1,16 +0,0 @@
|
||||
# Superset Development with GitHub Codespaces
|
||||
|
||||
For complete documentation on using GitHub Codespaces with Apache Superset, please see:
|
||||
|
||||
**[Setting up a Development Environment - GitHub Codespaces](https://superset.apache.org/docs/contributing/development#github-codespaces-cloud-development)**
|
||||
|
||||
## Pre-installed Development Environment
|
||||
|
||||
When you create a new Codespace from this repository, it automatically:
|
||||
|
||||
1. **Creates a Python virtual environment** using `uv venv`
|
||||
2. **Installs all development dependencies** via `uv pip install -r requirements/development.txt`
|
||||
3. **Sets up pre-commit hooks** with `pre-commit install`
|
||||
4. **Activates the virtual environment** automatically in all terminals
|
||||
|
||||
The virtual environment is located at `/workspaces/{repository-name}/.venv` and is automatically activated through environment variables set in the devcontainer configuration.
|
||||
@@ -1,62 +0,0 @@
|
||||
# Superset Codespaces environment setup
|
||||
# This file is appended to ~/.bashrc during Codespace setup
|
||||
|
||||
# Find the workspace directory (handles both 'superset' and 'superset-2' names)
|
||||
WORKSPACE_DIR=$(find /workspaces -maxdepth 1 -name "superset*" -type d | head -1)
|
||||
|
||||
if [ -n "$WORKSPACE_DIR" ]; then
|
||||
# Check if virtual environment exists
|
||||
if [ -d "$WORKSPACE_DIR/.venv" ]; then
|
||||
# Activate the virtual environment
|
||||
source "$WORKSPACE_DIR/.venv/bin/activate"
|
||||
echo "✅ Python virtual environment activated"
|
||||
|
||||
# Verify pre-commit is installed and set up
|
||||
if command -v pre-commit &> /dev/null; then
|
||||
echo "✅ pre-commit is available ($(pre-commit --version))"
|
||||
# Install git hooks if not already installed
|
||||
if [ -d "$WORKSPACE_DIR/.git" ] && [ ! -f "$WORKSPACE_DIR/.git/hooks/pre-commit" ]; then
|
||||
echo "🪝 Installing pre-commit hooks..."
|
||||
cd "$WORKSPACE_DIR" && pre-commit install
|
||||
fi
|
||||
else
|
||||
echo "⚠️ pre-commit not found. Run: pip install pre-commit"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Python virtual environment not found at $WORKSPACE_DIR/.venv"
|
||||
echo " Run: cd $WORKSPACE_DIR && .devcontainer/setup-dev.sh"
|
||||
fi
|
||||
|
||||
# Always cd to the workspace directory for convenience
|
||||
cd "$WORKSPACE_DIR"
|
||||
fi
|
||||
|
||||
# Add helpful aliases for Superset development
|
||||
alias start-superset="$WORKSPACE_DIR/.devcontainer/start-superset.sh"
|
||||
alias setup-dev="$WORKSPACE_DIR/.devcontainer/setup-dev.sh"
|
||||
|
||||
# Show helpful message on login
|
||||
echo ""
|
||||
echo "🚀 Superset Codespaces Environment"
|
||||
echo "=================================="
|
||||
|
||||
# Check if Superset is running
|
||||
if docker ps 2>/dev/null | grep -q "superset"; then
|
||||
echo "✅ Superset is running!"
|
||||
echo " - Check the 'Ports' tab for your live Superset URL"
|
||||
echo " - Initial startup takes 10-20 minutes"
|
||||
echo " - Login: admin/admin"
|
||||
else
|
||||
echo "⚠️ Superset is not running. Use: start-superset"
|
||||
# Check if there's a startup log
|
||||
if [ -f "/tmp/superset-startup.log" ]; then
|
||||
echo " 📋 Startup log found: cat /tmp/superset-startup.log"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Quick commands:"
|
||||
echo " start-superset - Start Superset with Docker Compose"
|
||||
echo " setup-dev - Set up Python environment (if not already done)"
|
||||
echo " pre-commit run - Run pre-commit checks on staged files"
|
||||
echo ""
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Script to build and push the devcontainer image to GitHub Container Registry
|
||||
# This allows caching the image between Codespace sessions
|
||||
|
||||
# You'll need to run this with appropriate GitHub permissions
|
||||
# gh auth login --scopes write:packages
|
||||
|
||||
REGISTRY="ghcr.io"
|
||||
OWNER="apache"
|
||||
REPO="superset"
|
||||
TAG="devcontainer-base"
|
||||
|
||||
echo "Building devcontainer image..."
|
||||
docker build -t $REGISTRY/$OWNER/$REPO:$TAG .devcontainer/
|
||||
|
||||
echo "Pushing to GitHub Container Registry..."
|
||||
docker push $REGISTRY/$OWNER/$REPO:$TAG
|
||||
|
||||
echo "Done! Update .devcontainer/devcontainer.json to use:"
|
||||
echo " \"image\": \"$REGISTRY/$OWNER/$REPO:$TAG\""
|
||||
@@ -1,66 +0,0 @@
|
||||
{
|
||||
"name": "Apache Superset Development",
|
||||
// Option 1: Use pre-built image directly
|
||||
// "image": "ghcr.io/apache/superset:devcontainer-base",
|
||||
|
||||
// Option 2: Build from Dockerfile with cache (current approach)
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
"context": ".",
|
||||
// Cache from the Apache registry image
|
||||
"cacheFrom": ["ghcr.io/apache/superset:devcontainer-base"]
|
||||
},
|
||||
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {
|
||||
"moby": true,
|
||||
"dockerDashComposeVersion": "v2"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "20"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/git:1": {},
|
||||
"ghcr.io/devcontainers/features/common-utils:2": {
|
||||
"configureZshAsDefaultShell": true
|
||||
},
|
||||
"ghcr.io/devcontainers/features/sshd:1": {
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
|
||||
// Forward ports for development
|
||||
"forwardPorts": [9001],
|
||||
"portsAttributes": {
|
||||
"9001": {
|
||||
"label": "Superset (via Webpack Dev Server)",
|
||||
"onAutoForward": "notify",
|
||||
"visibility": "public"
|
||||
}
|
||||
},
|
||||
|
||||
// Run commands after container is created
|
||||
"postCreateCommand": "bash .devcontainer/setup-dev.sh || echo '⚠️ Setup had issues - run .devcontainer/setup-dev.sh manually'",
|
||||
|
||||
// Auto-start Superset after ensuring Docker is ready
|
||||
// Run in foreground to see any errors, but don't block on failures
|
||||
"postStartCommand": "bash -c 'echo \"Waiting 30s for services to initialize...\"; sleep 30; .devcontainer/start-superset.sh || echo \"⚠️ Auto-start failed - run start-superset manually\"'",
|
||||
|
||||
// Set environment variables
|
||||
"remoteEnv": {
|
||||
// Removed automatic venv activation to prevent startup issues
|
||||
// The setup script will handle this
|
||||
},
|
||||
|
||||
// VS Code customizations
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-python.python",
|
||||
"ms-python.vscode-pylance",
|
||||
"charliermarsh.ruff",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Setup script for Superset Codespaces development environment
|
||||
|
||||
echo "🔧 Setting up Superset development environment..."
|
||||
|
||||
# System dependencies and uv are now pre-installed in the Docker image
|
||||
# This speeds up Codespace creation significantly!
|
||||
|
||||
# Create virtual environment using uv
|
||||
echo "🐍 Creating Python virtual environment..."
|
||||
if ! uv venv; then
|
||||
echo "❌ Failed to create virtual environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install Python dependencies
|
||||
echo "📦 Installing Python dependencies..."
|
||||
if ! uv pip install -r requirements/development.txt; then
|
||||
echo "❌ Failed to install Python dependencies"
|
||||
echo "💡 You may need to run this manually after the Codespace starts"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install pre-commit hooks
|
||||
echo "🪝 Installing pre-commit hooks..."
|
||||
if source .venv/bin/activate && pre-commit install; then
|
||||
echo "✅ Pre-commit hooks installed"
|
||||
else
|
||||
echo "⚠️ Pre-commit hooks installation failed (non-critical)"
|
||||
fi
|
||||
|
||||
# Install Claude Code CLI via npm
|
||||
echo "🤖 Installing Claude Code..."
|
||||
if npm install -g @anthropic-ai/claude-code; then
|
||||
echo "✅ Claude Code installed"
|
||||
else
|
||||
echo "⚠️ Claude Code installation failed (non-critical)"
|
||||
fi
|
||||
|
||||
# Make the start script executable
|
||||
chmod +x .devcontainer/start-superset.sh
|
||||
|
||||
# Add bashrc additions for automatic venv activation
|
||||
echo "🔧 Setting up automatic environment activation..."
|
||||
if [ -f ~/.bashrc ]; then
|
||||
# Check if we've already added our additions
|
||||
if ! grep -q "Superset Codespaces environment setup" ~/.bashrc; then
|
||||
echo "" >> ~/.bashrc
|
||||
cat .devcontainer/bashrc-additions >> ~/.bashrc
|
||||
echo "✅ Added automatic venv activation to ~/.bashrc"
|
||||
else
|
||||
echo "✅ Bashrc additions already present"
|
||||
fi
|
||||
else
|
||||
# Create bashrc if it doesn't exist
|
||||
cat .devcontainer/bashrc-additions > ~/.bashrc
|
||||
echo "✅ Created ~/.bashrc with automatic venv activation"
|
||||
fi
|
||||
|
||||
# Also add to zshrc since that's the default shell
|
||||
if [ -f ~/.zshrc ] || [ -n "$ZSH_VERSION" ]; then
|
||||
if ! grep -q "Superset Codespaces environment setup" ~/.zshrc; then
|
||||
echo "" >> ~/.zshrc
|
||||
cat .devcontainer/bashrc-additions >> ~/.zshrc
|
||||
echo "✅ Added automatic venv activation to ~/.zshrc"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✅ Development environment setup complete!"
|
||||
echo ""
|
||||
echo "📝 The virtual environment will be automatically activated in new terminals"
|
||||
echo ""
|
||||
echo "🔄 To activate in this terminal, run:"
|
||||
echo " source ~/.bashrc"
|
||||
echo ""
|
||||
echo "🚀 To start Superset:"
|
||||
echo " start-superset"
|
||||
echo ""
|
||||
@@ -1,108 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Startup script for Superset in Codespaces
|
||||
|
||||
# Log to a file for debugging
|
||||
LOG_FILE="/tmp/superset-startup.log"
|
||||
echo "[$(date)] Starting Superset startup script" >> "$LOG_FILE"
|
||||
echo "[$(date)] User: $(whoami), PWD: $(pwd)" >> "$LOG_FILE"
|
||||
|
||||
echo "🚀 Starting Superset in Codespaces..."
|
||||
echo "🌐 Frontend will be available at port 9001"
|
||||
|
||||
# Find the workspace directory (Codespaces clones as 'superset', not 'superset-2')
|
||||
WORKSPACE_DIR=$(find /workspaces -maxdepth 1 -name "superset*" -type d | head -1)
|
||||
if [ -n "$WORKSPACE_DIR" ]; then
|
||||
cd "$WORKSPACE_DIR"
|
||||
echo "📁 Working in: $WORKSPACE_DIR"
|
||||
else
|
||||
echo "📁 Using current directory: $(pwd)"
|
||||
fi
|
||||
|
||||
# Wait for Docker to be available
|
||||
echo "⏳ Waiting for Docker to start..."
|
||||
echo "[$(date)] Waiting for Docker..." >> "$LOG_FILE"
|
||||
max_attempts=30
|
||||
attempt=0
|
||||
while ! docker info > /dev/null 2>&1; do
|
||||
if [ $attempt -eq $max_attempts ]; then
|
||||
echo "❌ Docker failed to start after $max_attempts attempts"
|
||||
echo "[$(date)] Docker failed to start after $max_attempts attempts" >> "$LOG_FILE"
|
||||
echo "🔄 Please restart the Codespace or run this script manually later"
|
||||
exit 1
|
||||
fi
|
||||
echo " Attempt $((attempt + 1))/$max_attempts..."
|
||||
echo "[$(date)] Docker check attempt $((attempt + 1))/$max_attempts" >> "$LOG_FILE"
|
||||
sleep 2
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
echo "✅ Docker is ready!"
|
||||
echo "[$(date)] Docker is ready" >> "$LOG_FILE"
|
||||
|
||||
# Check if Superset containers are already running
|
||||
if docker ps | grep -q "superset"; then
|
||||
echo "✅ Superset containers are already running!"
|
||||
echo ""
|
||||
echo "🌐 To access Superset:"
|
||||
echo " 1. Click the 'Ports' tab at the bottom of VS Code"
|
||||
echo " 2. Find port 9001 and click the globe icon to open"
|
||||
echo " 3. Wait 10-20 minutes for initial startup"
|
||||
echo ""
|
||||
echo "📝 Login credentials: admin/admin"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Clean up any existing containers
|
||||
echo "🧹 Cleaning up existing containers..."
|
||||
docker-compose -f docker-compose-light.yml down
|
||||
|
||||
# Start services
|
||||
echo "🏗️ Starting Superset in background (daemon mode)..."
|
||||
echo ""
|
||||
|
||||
# Start in detached mode
|
||||
docker-compose -f docker-compose-light.yml up -d
|
||||
|
||||
echo ""
|
||||
echo "✅ Docker Compose started successfully!"
|
||||
echo ""
|
||||
echo "📋 Important information:"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "⏱️ Initial startup takes 10-20 minutes"
|
||||
echo "🌐 Check the 'Ports' tab for your Superset URL (port 9001)"
|
||||
echo "👤 Login: admin / admin"
|
||||
echo ""
|
||||
echo "📊 Useful commands:"
|
||||
echo " docker-compose -f docker-compose-light.yml logs -f # Follow logs"
|
||||
echo " docker-compose -f docker-compose-light.yml ps # Check status"
|
||||
echo " docker-compose -f docker-compose-light.yml down # Stop services"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "💤 Keeping terminal open for 60 seconds to test persistence..."
|
||||
sleep 60
|
||||
echo "✅ Test complete - check if this terminal is still visible!"
|
||||
|
||||
# Show final status
|
||||
docker-compose -f docker-compose-light.yml ps
|
||||
EXIT_CODE=$?
|
||||
|
||||
# If it failed, provide helpful instructions
|
||||
if [ $EXIT_CODE -ne 0 ] && [ $EXIT_CODE -ne 130 ]; then # 130 is Ctrl+C
|
||||
echo ""
|
||||
echo "❌ Superset startup failed (exit code: $EXIT_CODE)"
|
||||
echo ""
|
||||
echo "🔄 To restart Superset, run:"
|
||||
echo " .devcontainer/start-superset.sh"
|
||||
echo ""
|
||||
echo "🔧 For troubleshooting:"
|
||||
echo " # View logs:"
|
||||
echo " docker-compose -f docker-compose-light.yml logs"
|
||||
echo ""
|
||||
echo " # Clean restart (removes volumes):"
|
||||
echo " docker-compose -f docker-compose-light.yml down -v"
|
||||
echo " .devcontainer/start-superset.sh"
|
||||
echo ""
|
||||
echo " # Common issues:"
|
||||
echo " - Network timeouts: Just retry, often transient"
|
||||
echo " - Port conflicts: Check 'docker ps'"
|
||||
echo " - Database issues: Try clean restart with -v"
|
||||
fi
|
||||
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -2,7 +2,7 @@
|
||||
|
||||
# https://github.com/apache/superset/issues/13351
|
||||
|
||||
/superset/migrations/ @mistercrunch @michael-s-molina @betodealmeida @eschutho @sadpandajoe
|
||||
/superset/migrations/ @mistercrunch @michael-s-molina @betodealmeida @eschutho
|
||||
|
||||
# Notify some committers of changes in the components
|
||||
|
||||
|
||||
2
.github/workflows/welcome-new-users.yml
vendored
2
.github/workflows/welcome-new-users.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Welcome Message
|
||||
uses: actions/first-interaction@v2
|
||||
uses: actions/first-interaction@v1
|
||||
continue-on-error: true
|
||||
with:
|
||||
repo-token: ${{ github.token }}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -131,6 +131,3 @@ superset/static/stats/statistics.html
|
||||
# LLM-related
|
||||
CLAUDE.local.md
|
||||
.aider*
|
||||
.claude_rc*
|
||||
.env.local
|
||||
PROJECT.md
|
||||
|
||||
@@ -44,8 +44,4 @@ under the License.
|
||||
- [4.0.1](./CHANGELOG/4.0.1.md)
|
||||
- [4.0.2](./CHANGELOG/4.0.2.md)
|
||||
- [4.1.0](./CHANGELOG/4.1.0.md)
|
||||
- [4.1.1](./CHANGELOG/4.1.1.md)
|
||||
- [4.1.2](./CHANGELOG/4.1.2.md)
|
||||
- [4.1.3](./CHANGELOG/4.1.3.md)
|
||||
- [5.0.0](./CHANGELOG/5.0.0.md)
|
||||
- [6.0.0](./CHANGELOG/6.0.0.md)
|
||||
|
||||
@@ -1,801 +0,0 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
## Change Log
|
||||
|
||||
### 6.0 (Mon Aug 18 14:04:26 2025 -0700)
|
||||
|
||||
**Database Migrations**
|
||||
|
||||
- [#34560](https://github.com/apache/superset/pull/34560) feat: Implement UI-based system theme administration (@mistercrunch)
|
||||
- [#34521](https://github.com/apache/superset/pull/34521) chore: use logger on all migrations (@villebro)
|
||||
- [#34345](https://github.com/apache/superset/pull/34345) chore: proper current_app.config proxy usage (@mistercrunch)
|
||||
- [#34182](https://github.com/apache/superset/pull/34182) feat: add a theme CRUD page to manage themes (@mistercrunch)
|
||||
- [#34292](https://github.com/apache/superset/pull/34292) chore: move some rules from ruff -> pylint (@mistercrunch)
|
||||
- [#33682](https://github.com/apache/superset/pull/33682) fix: Dataset currency (@Vitor-Avila)
|
||||
- [#33564](https://github.com/apache/superset/pull/33564) chore: remove sqlparse (@betodealmeida)
|
||||
- [#33303](https://github.com/apache/superset/pull/33303) fix: `metric.currency` should be JSON, not string (@betodealmeida)
|
||||
- [#33155](https://github.com/apache/superset/pull/33155) chore: migrate to more db migration utils (@eschutho)
|
||||
- [#33072](https://github.com/apache/superset/pull/33072) chore: use create table util (@eschutho)
|
||||
- [#33116](https://github.com/apache/superset/pull/33116) feat(explore): X-axis sort by specific metric when more than 1 metric is set (@kgabryje)
|
||||
- [#32852](https://github.com/apache/superset/pull/32852) chore: update migrations to use utils (@sadpandajoe)
|
||||
- [#32759](https://github.com/apache/superset/pull/32759) fix(migrations): fix foreign keys to match FAB 4.6.0 tables (@Antonio-RiveroMartnez)
|
||||
- [#32680](https://github.com/apache/superset/pull/32680) feat: DB migration for dataset folders (@betodealmeida)
|
||||
- [#32352](https://github.com/apache/superset/pull/32352) fix(dev/ci): pre-commit fixes galore (@rusackas)
|
||||
|
||||
**Features**
|
||||
|
||||
- [#34732](https://github.com/apache/superset/pull/34732) feat: completely migrate from DeprecatedThemeColors to Antd semantic tokens (@mistercrunch)
|
||||
- [#29573](https://github.com/apache/superset/pull/29573) feat(api): Added uuid filed support to dataset, chart, dashboard API (@dankor)
|
||||
- [#34712](https://github.com/apache/superset/pull/34712) feat: replace react-color with AntD ColorPicker for theming support (@mistercrunch)
|
||||
- [#34678](https://github.com/apache/superset/pull/34678) feat(extension): Add extension for chart header (@justinpark)
|
||||
- [#34658](https://github.com/apache/superset/pull/34658) feat(sqllab): improve SaveDatasetModal design with proper theme spacing (@kasiazjc)
|
||||
- [#27086](https://github.com/apache/superset/pull/27086) feat(filter_state): Added @api and @has_access_api to all methods of filter_state API. (@xneg)
|
||||
- [#34663](https://github.com/apache/superset/pull/34663) feat: add @sadpandajoe to migrations CODEOWNERS (@mistercrunch)
|
||||
- [#34655](https://github.com/apache/superset/pull/34655) feat(dashboard): change chart background option from "White" to "Solid" (@kasiazjc)
|
||||
- [#34561](https://github.com/apache/superset/pull/34561) feat: Tiled screenshots in Playwright reports (@kgabryje)
|
||||
- [#34434](https://github.com/apache/superset/pull/34434) feat: Add ESLint rule to enforce sentence case in button text (@sadpandajoe)
|
||||
- [#34322](https://github.com/apache/superset/pull/34322) feat(deckgl): add selected cross-filter indication (@DamianPendrak)
|
||||
- [#34373](https://github.com/apache/superset/pull/34373) feat(docker): Add pytest support to docker-compose-light.yml (@mistercrunch)
|
||||
- [#34375](https://github.com/apache/superset/pull/34375) feat(timeshift): Add support for date range timeshifts (@msyavuz)
|
||||
- [#34319](https://github.com/apache/superset/pull/34319) feat: Enable drilling in embedded (@Vitor-Avila)
|
||||
- [#34406](https://github.com/apache/superset/pull/34406) feat: Add configurable query identifiers for Mixed Timeseries charts (@yousoph)
|
||||
- [#34416](https://github.com/apache/superset/pull/34416) feat: add runtime custom font loading via configuration (@mistercrunch)
|
||||
- [#34409](https://github.com/apache/superset/pull/34409) feat(codespaces): auto-setup Python venv with dependencies (@mistercrunch)
|
||||
- [#34206](https://github.com/apache/superset/pull/34206) feat(i18n): update Spanish translations (messages.po) (@cbausaonebox)
|
||||
- [#34376](https://github.com/apache/superset/pull/34376) feat: Add GitHub Codespaces support with docker-compose-light (@mistercrunch)
|
||||
- [#34383](https://github.com/apache/superset/pull/34383) feat(charts): Enable async buildQuery support for complex chart logic (@mistercrunch)
|
||||
- [#34380](https://github.com/apache/superset/pull/34380) feat: allow creating dataset without exploring (@betodealmeida)
|
||||
- [#34379](https://github.com/apache/superset/pull/34379) feat: focus on text input when modal opens (@betodealmeida)
|
||||
- [#34359](https://github.com/apache/superset/pull/34359) feat: read column metadata (@betodealmeida)
|
||||
- [#34273](https://github.com/apache/superset/pull/34273) feat(theming): Align embedded sdk with theme configs (@gabotorresruiz)
|
||||
- [#34324](https://github.com/apache/superset/pull/34324) feat: introducing a docker-compose-light.yml for lighter development (@mistercrunch)
|
||||
- [#34308](https://github.com/apache/superset/pull/34308) feat(timeseries): enhance 'Series Limit' to support grouping the long tail (@mistercrunch)
|
||||
- [#34294](https://github.com/apache/superset/pull/34294) feat: re-order CRUD list view action buttons (@mistercrunch)
|
||||
- [#34290](https://github.com/apache/superset/pull/34290) feat: make `SupersetClient` retry on 502-504 (@betodealmeida)
|
||||
- [#34258](https://github.com/apache/superset/pull/34258) feat(docker): do not include chromium (headless browser) by default in Dockerfile (@mistercrunch)
|
||||
- [#34194](https://github.com/apache/superset/pull/34194) feat: introduce comprehensive LLM context guides for AI-powered development (@mistercrunch)
|
||||
- [#34207](https://github.com/apache/superset/pull/34207) feat(docs): migrate ESLint to v9 (@hainenber)
|
||||
- [#34231](https://github.com/apache/superset/pull/34231) feat: add Claude Code GitHub Action integration (@mistercrunch)
|
||||
- [#34204](https://github.com/apache/superset/pull/34204) feat(deckgl): add support for OpenStreetMap as our new default and make "tile-providers" more configurable FIX (@plavacquery)
|
||||
- [#33569](https://github.com/apache/superset/pull/33569) feat(pivot-table-chart): Download as pivoted excel (@mdusmanalvi)
|
||||
- [#34156](https://github.com/apache/superset/pull/34156) feat(snowflake): Support Snowflake private keys w/o passphrase (@junyoneyama)
|
||||
- [#33953](https://github.com/apache/superset/pull/33953) feat(i18n): add Catalan (ca) translations (@cbausaonebox)
|
||||
- [#34177](https://github.com/apache/superset/pull/34177) feat: removing dup logic in sqla/models.py and models/helpers.py (@mistercrunch)
|
||||
- [#34144](https://github.com/apache/superset/pull/34144) feat(theming): Introduce bootstrap-driven Superset theme configurations (@gabotorresruiz)
|
||||
- [#32870](https://github.com/apache/superset/pull/32870) feat(filter panel): hide filter panel on all dashboard by default. (@SBIN2010)
|
||||
- [#34119](https://github.com/apache/superset/pull/34119) feat(i18n): load language pack asynchronously (@mistercrunch)
|
||||
- [#34140](https://github.com/apache/superset/pull/34140) feat: improve Doris catalog support (@betodealmeida)
|
||||
- [#34017](https://github.com/apache/superset/pull/34017) feat(deckgl): add new color controls with color breakpoints (@DamianPendrak)
|
||||
- [#33603](https://github.com/apache/superset/pull/33603) feat(deckgl): add support for OpenStreetMap as our new default and make "tile-providers" more configurable (@plavacquery)
|
||||
- [#33769](https://github.com/apache/superset/pull/33769) feat(deck-gl): Enable individual deck.gl layer selection in FilterScope tree (@richardfogaca)
|
||||
- [#34095](https://github.com/apache/superset/pull/34095) feat: Don't show the row limit warning for embedded dashboards by default (@Vitor-Avila)
|
||||
- [#33517](https://github.com/apache/superset/pull/33517) feat(viz-type): Ag grid table plugin Integration (@amaannawab923)
|
||||
- [#33789](https://github.com/apache/superset/pull/33789) feat(deckgl): add cross-filters to deck.gl charts (@DamianPendrak)
|
||||
- [#33170](https://github.com/apache/superset/pull/33170) feat(filter): Add Slider Range Inputs Option for Numerical Range Filters (@payose)
|
||||
- [#33716](https://github.com/apache/superset/pull/33716) feat(plugin-chart-echarts): add Gantt Chart plugin (@Quatters)
|
||||
- [#34023](https://github.com/apache/superset/pull/34023) feat(flag): Added feature_flag for superset security_views (@alexandrusoare)
|
||||
- [#33809](https://github.com/apache/superset/pull/33809) feat: Add confirmation modal for unsaved changes (@gabotorresruiz)
|
||||
- [#33947](https://github.com/apache/superset/pull/33947) feat(Table): Add infrastructure to override time shifts (@msyavuz)
|
||||
- [#33929](https://github.com/apache/superset/pull/33929) feat(db): remove Rockset DB support (@hainenber)
|
||||
- [#33781](https://github.com/apache/superset/pull/33781) feat(Dashboard): Row limit warning in dashboards (@msyavuz)
|
||||
- [#33631](https://github.com/apache/superset/pull/33631) feat(User Registrations): Migrate user registrations fab view (@msyavuz)
|
||||
- [#33871](https://github.com/apache/superset/pull/33871) feat(charts): Add row limit control to box plot chart (@DamianPendrak)
|
||||
- [#33863](https://github.com/apache/superset/pull/33863) feat(Icons): Add HistoryOutlined (@msyavuz)
|
||||
- [#33851](https://github.com/apache/superset/pull/33851) feat(theming): improving theme docs and configuration (@mistercrunch)
|
||||
- [#31590](https://github.com/apache/superset/pull/31590) feat(theming): land Ant Design v5 overhaul — dynamic themes, real dark mode + massive styling refactor (@mistercrunch)
|
||||
- [#33847](https://github.com/apache/superset/pull/33847) feat: initial Dremio sqlglot dialect (@betodealmeida)
|
||||
- [#33829](https://github.com/apache/superset/pull/33829) feat(extension): Added extension point for Time Filters (@alexandrusoare)
|
||||
- [#33656](https://github.com/apache/superset/pull/33656) feat(chart): add toggle for percentage metric calculation mode in Table chart (@LevisNgigi)
|
||||
- [#33709](https://github.com/apache/superset/pull/33709) feat(DatasourceEditor): Format sql shortcut and bigger table (@msyavuz)
|
||||
- [#33729](https://github.com/apache/superset/pull/33729) feat: x axis interval control to show ALL ticks on timeseries charts (@rusackas)
|
||||
- [#32610](https://github.com/apache/superset/pull/32610) feat(clickhouse): allow dynamic schema (@codenamelxl)
|
||||
- [#33634](https://github.com/apache/superset/pull/33634) feat(MixedTimeSeries): Add onlyTotal and Sort Series to Mixed TimeSeries (@nilmonto)
|
||||
- [#33443](https://github.com/apache/superset/pull/33443) feat(Dataset): editor improvements - run in sqllab (@rebenitez1802)
|
||||
- [#33620](https://github.com/apache/superset/pull/33620) feat(UserInfo): Migrate User Info FAB to React (@EnxDev)
|
||||
- [#33301](https://github.com/apache/superset/pull/33301) feat(List Groups): Migrate List Groups FAB to React (@EnxDev)
|
||||
- [#32887](https://github.com/apache/superset/pull/32887) feat(database): add SingleStore engine specification (@AdalbertMemSQL)
|
||||
- [#33434](https://github.com/apache/superset/pull/33434) feat: Python 3.12 support (@rad-pat)
|
||||
- [#33560](https://github.com/apache/superset/pull/33560) feat: use sqlglot to validate adhoc subquery (@betodealmeida)
|
||||
- [#33542](https://github.com/apache/superset/pull/33542) feat(sqllab): use sqlglot instead of sqlparse (@betodealmeida)
|
||||
- [#33614](https://github.com/apache/superset/pull/33614) feat: current_user_rls_rules Jinja macro (@Vitor-Avila)
|
||||
- [#33525](https://github.com/apache/superset/pull/33525) feat: implement CVAS/CTAS in sqlglot (@betodealmeida)
|
||||
- [#33524](https://github.com/apache/superset/pull/33524) feat: implement RLS in sqlglot (@betodealmeida)
|
||||
- [#33518](https://github.com/apache/superset/pull/33518) feat: implement CTEs logic in sqlglot (@betodealmeida)
|
||||
- [#33298](https://github.com/apache/superset/pull/33298) feat(Action Logs): Migrate Action Log FAB to React (@EnxDev)
|
||||
- [#33473](https://github.com/apache/superset/pull/33473) feat: use sqlglot to set limit (@betodealmeida)
|
||||
- [#33456](https://github.com/apache/superset/pull/33456) feat: implement limit extraction in sqlglot (@betodealmeida)
|
||||
- [#32707](https://github.com/apache/superset/pull/32707) feat(stack by dimension): add a stack by dimension dropdown list (@jpchev)
|
||||
- [#33451](https://github.com/apache/superset/pull/33451) feat(chart): add dynamicQueryObjectCount property to Chart Metadata (@DamianPendrak)
|
||||
- [#33348](https://github.com/apache/superset/pull/33348) feat(Pie Chart): threshold for Other (@Quatters)
|
||||
- [#33357](https://github.com/apache/superset/pull/33357) feat(Table Chart): Row limit Increase , Backend Sorting , Backend Search , Excel/CSV Improvements (@amaannawab923)
|
||||
- [#33340](https://github.com/apache/superset/pull/33340) feat: Run SQL on DataSourceEditor implementation (@rebenitez1802)
|
||||
- [#33099](https://github.com/apache/superset/pull/33099) feat: add metric name for big number chart types #33013 (@fardin-developer)
|
||||
- [#29580](https://github.com/apache/superset/pull/29580) feat: Persian translations (@CodeWithEmad)
|
||||
- [#33208](https://github.com/apache/superset/pull/33208) feat(maps): Adding Republic of Serbia to country maps (@rusackas)
|
||||
- [#33192](https://github.com/apache/superset/pull/33192) feat(i18n): Frontend add zh_TW Option (@bestlong)
|
||||
- [#33198](https://github.com/apache/superset/pull/33198) feat(maps): Adding Ivory Coast / Côte d'Ivoire (@rusackas)
|
||||
- [#32695](https://github.com/apache/superset/pull/32695) feat(country-map): fix France Regions IDF region code - Fixes #32627 (@tarraschk)
|
||||
- [#33043](https://github.com/apache/superset/pull/33043) feat(Select): Select all and Deselect all that works on visible items while searching (@msyavuz)
|
||||
- [#33054](https://github.com/apache/superset/pull/33054) feat(Native Filters): Exclude Filter Values (@amaannawab923)
|
||||
- [#32882](https://github.com/apache/superset/pull/32882) feat(List Users): Migrate List Users FAB to React (@EnxDev)
|
||||
- [#29827](https://github.com/apache/superset/pull/29827) feat(lang): update Italian language (@WLCFaro)
|
||||
- [#33104](https://github.com/apache/superset/pull/33104) feat(explore): Integrate dataset panel with Folders feature (@eschutho)
|
||||
- [#28751](https://github.com/apache/superset/pull/28751) feat: catalogs for DuckDB (@betodealmeida)
|
||||
- [#32520](https://github.com/apache/superset/pull/32520) feat: dataset folders (backend) (@betodealmeida)
|
||||
- [#33096](https://github.com/apache/superset/pull/33096) feat(Native Filters): Configure creatable filter behavior (@geido)
|
||||
- [#33000](https://github.com/apache/superset/pull/33000) feat: optimize catalog permission sync (@betodealmeida)
|
||||
- [#32975](https://github.com/apache/superset/pull/32975) feat(charts): add subtitle option and metric customization controls (@LevisNgigi)
|
||||
- [#30134](https://github.com/apache/superset/pull/30134) feat: Allow superset to be deployed under a prefixed URL (@martyngigg)
|
||||
- [#33046](https://github.com/apache/superset/pull/33046) feat: add a title prop to the dashboard link in CRUD LIST view (@mistercrunch)
|
||||
- [#30833](https://github.com/apache/superset/pull/30833) feat(tags): Export and Import Functionality for Superset Dashboards and Charts (@asher-lab)
|
||||
- [#32997](https://github.com/apache/superset/pull/32997) feat: Add getDataMask function to embedded SDK (@kgabryje)
|
||||
- [#31331](https://github.com/apache/superset/pull/31331) feat(embedding-sdk): emit data-mask events through embedded sdk to iframe parent (@MohamedHalat)
|
||||
- [#32432](https://github.com/apache/superset/pull/32432) feat(List Roles): Migrate FAB view to React (@EnxDev)
|
||||
- [#30760](https://github.com/apache/superset/pull/30760) feat: add latest partition support for BigQuery (@mistercrunch)
|
||||
- [#32900](https://github.com/apache/superset/pull/32900) feat: Enable passing a permalink to cache_dashboard_screenshot endpoint (@kgabryje)
|
||||
- [#28605](https://github.com/apache/superset/pull/28605) feat(plugins): Make comparison values on BigNumberPeriodOverPeriod toggleable (@mkramer5454)
|
||||
- [#32814](https://github.com/apache/superset/pull/32814) feat(chart controls): Add "%d.%m.%Y" time format option (@Quatters)
|
||||
- [#32767](https://github.com/apache/superset/pull/32767) feat: Add Aggregation Method for Big Number with Trendline (@LevisNgigi)
|
||||
- [#32770](https://github.com/apache/superset/pull/32770) feat: Add current_user_roles() Jinja macro (@bmaquet)
|
||||
- [#32781](https://github.com/apache/superset/pull/32781) feat(Jinja): to_datetime filter (@Vitor-Avila)
|
||||
- [#32721](https://github.com/apache/superset/pull/32721) feat(FormModal): Specialized Modal component for forms (@alexandrusoare)
|
||||
- [#32735](https://github.com/apache/superset/pull/32735) feat(embedded): Force a specific referrerPolicy for the iframe request (@Vitor-Avila)
|
||||
- [#32731](https://github.com/apache/superset/pull/32731) feat(where_in): Support returning None if filter_values return None (@Vitor-Avila)
|
||||
- [#32702](https://github.com/apache/superset/pull/32702) feat(file uploads): List only allowed schemas in the file uploads dialog (@Vitor-Avila)
|
||||
- [#32670](https://github.com/apache/superset/pull/32670) feat: Implement sparse import for ImportAssetsCommand (@withnale)
|
||||
- [#32682](https://github.com/apache/superset/pull/32682) feat(docs): Adding Kapa.ai integration (@rusackas)
|
||||
- [#32662](https://github.com/apache/superset/pull/32662) feat: add a note to install cors-related dependency when using ENABLE_CORS (@mistercrunch)
|
||||
- [#32546](https://github.com/apache/superset/pull/32546) feat: `OAuth2StoreTokenCommand` (@betodealmeida)
|
||||
- [#32366](https://github.com/apache/superset/pull/32366) feat(reports): removing index column (@SkinnyPigeon)
|
||||
- [#32170](https://github.com/apache/superset/pull/32170) feat(charts): add two new boxplot parameter sets (@sfirke)
|
||||
- [#32510](https://github.com/apache/superset/pull/32510) feat(slack): adds rate limit error handler for Slack client (@Usiel)
|
||||
- [#32509](https://github.com/apache/superset/pull/32509) feat(KustoKQL): Update KQL alchemy version and update timegrain expressions (@ag-ramachandran)
|
||||
- [#32506](https://github.com/apache/superset/pull/32506) feat: make user agent customizable (@villebro)
|
||||
- [#32317](https://github.com/apache/superset/pull/32317) feat(flag flip): Setting Horizontal Filters to True by default. (@rusackas)
|
||||
- [#32121](https://github.com/apache/superset/pull/32121) feat: security, user group support (@dpgaspar)
|
||||
- [#31996](https://github.com/apache/superset/pull/31996) feat: cache the frontend's bootstrap data (@mistercrunch)
|
||||
- [#32048](https://github.com/apache/superset/pull/32048) feat: improve GSheets OAuth2 (@betodealmeida)
|
||||
- [#32231](https://github.com/apache/superset/pull/32231) feat: Update database permissions in async mode (@Vitor-Avila)
|
||||
- [#31726](https://github.com/apache/superset/pull/31726) feat(filter): adding inputs to Numerical Range Filter (@alexandrusoare)
|
||||
- [#31506](https://github.com/apache/superset/pull/31506) feat(i18n): Add polish to default language (@EmmanuelCbd)
|
||||
- [#32403](https://github.com/apache/superset/pull/32403) feat: default ports for SSH tunnel (@betodealmeida)
|
||||
- [#32358](https://github.com/apache/superset/pull/32358) feat: Adding the option and feature to enable borders with color, opacity and width control on heatmaps along with white borders on emphasis (@Dev10-34)
|
||||
- [#32339](https://github.com/apache/superset/pull/32339) feat: allow importing encrypted_extra (@betodealmeida)
|
||||
- [#32264](https://github.com/apache/superset/pull/32264) feat(number-format): adds memory data transfer rates in binary and decimal format (@tshallenberger)
|
||||
- [#32261](https://github.com/apache/superset/pull/32261) feat(type-checking): Add type-checking pre-commit hooks (@alveifbklsiu259)
|
||||
- [#32228](https://github.com/apache/superset/pull/32228) feat: recursive metric definitions (@betodealmeida)
|
||||
- [#32189](https://github.com/apache/superset/pull/32189) feat(dropdown accessibility): Wrap dropdown triggers with buttons for accessibility (@msyavuz)
|
||||
- [#31998](https://github.com/apache/superset/pull/31998) feat: Add parseJson Handlebars Helper to Support Processing Nested JSON Data (@AdrianKoszalka)
|
||||
- [#31998](https://github.com/apache/superset/pull/31998) feat: Add parseJson Handlebars Helper to Support Processing Nested JSON Data (@AdrianKoszalka)
|
||||
- [#32041](https://github.com/apache/superset/pull/32041) feat: add TDengine.py driver to db_engine (@DuanKuanJun)
|
||||
|
||||
**Fixes**
|
||||
|
||||
- [#34676](https://github.com/apache/superset/pull/34676) fix(theming): Some visual issues (@rebenitez1802)
|
||||
- [#34660](https://github.com/apache/superset/pull/34660) fix: Table chart server side pagination not working on dashboard (@kgabryje)
|
||||
- [#34708](https://github.com/apache/superset/pull/34708) fix(dashboard): Remove Tab from Dashboard Confirm Modal themed (@rebenitez1802)
|
||||
- [#34706](https://github.com/apache/superset/pull/34706) fix(dashboard): Titles tooltip flickering (@rebenitez1802)
|
||||
- [#34654](https://github.com/apache/superset/pull/34654) fix: centralize cache timeout -1 logic to prevent caching (@dpgaspar)
|
||||
- [#34686](https://github.com/apache/superset/pull/34686) fix(ag-grid): Fix broken string column filters in AG Grid Table V2 (@amaannawab923)
|
||||
- [#34418](https://github.com/apache/superset/pull/34418) fix(dashboard): update cross filter scoping chart id references during dashboard import (@trentontrees)
|
||||
- [#34690](https://github.com/apache/superset/pull/34690) fix(deck.gl): add webpack rule to define module global for deck.gl charts (@richardfogaca)
|
||||
- [#34698](https://github.com/apache/superset/pull/34698) fix: Invalid error tooltip if control label is function (@kgabryje)
|
||||
- [#34671](https://github.com/apache/superset/pull/34671) fix: Bar chart crash when switching from Big Number (@kgabryje)
|
||||
- [#34680](https://github.com/apache/superset/pull/34680) fix(bootstrapData): Missing application_root data throws an error (@justinpark)
|
||||
- [#34675](https://github.com/apache/superset/pull/34675) fix(theming): Fix ag-grid theming regression in SQL Lab (@mistercrunch)
|
||||
- [#34672](https://github.com/apache/superset/pull/34672) fix(row_level_security): Correct api response code for update (@msyavuz)
|
||||
- [#34585](https://github.com/apache/superset/pull/34585) fix(theming): Theming visual fixes p5 (@msyavuz)
|
||||
- [#34664](https://github.com/apache/superset/pull/34664) fix(csv_tests): Import from utils (@msyavuz)
|
||||
- [#34511](https://github.com/apache/superset/pull/34511) fix(sqllab): show actual execution duration in Query History (@rusackas)
|
||||
- [#34395](https://github.com/apache/superset/pull/34395) fix(superset-ui-core): Include appRoot in endpoint of SupersetClientClass.postForm action (@martyngigg)
|
||||
- [#34304](https://github.com/apache/superset/pull/34304) fix(presto): return proper data type for column (@betodealmeida)
|
||||
- [#32340](https://github.com/apache/superset/pull/32340) fix(security): grant TableSchemaView to only sql_lab role (@codenamelxl)
|
||||
- [#33503](https://github.com/apache/superset/pull/33503) fix: activity table delta time (@natilehrer)
|
||||
- [#33202](https://github.com/apache/superset/pull/33202) fix(open-api): Add missing FormatQueryPayloadSchema and DashboardScreenshotPostSchema to open-api component schemas (@dogfootruler-kr)
|
||||
- [#32405](https://github.com/apache/superset/pull/32405) fix(daos/tag): prevent non-unique tags getting created along with unique ones (@hainenber)
|
||||
- [#21083](https://github.com/apache/superset/pull/21083) fix(install): set SUPERSET_VERSION_RC at the right time (@Joel-Haeberli)
|
||||
- [#34645](https://github.com/apache/superset/pull/34645) fix(webpack): webpack warnings (@gabotorresruiz)
|
||||
- [#34005](https://github.com/apache/superset/pull/34005) fix: update Russian translations (@PolinaFam)
|
||||
- [#34644](https://github.com/apache/superset/pull/34644) fix: Fix Slice import on has_drill_by_access (@Vitor-Avila)
|
||||
- [#34641](https://github.com/apache/superset/pull/34641) fix: Slack channels and Color Palettes search (@Vitor-Avila)
|
||||
- [#34584](https://github.com/apache/superset/pull/34584) fix(initialization): prevent startup failures when database tables don't exist (@eschutho)
|
||||
- [#34625](https://github.com/apache/superset/pull/34625) fix: Remove deprecated @types/classnames package (@rusackas)
|
||||
- [#34602](https://github.com/apache/superset/pull/34602) fix(Dashboards): Tabs highlight and dataset contrast in darkmode issues (@rebenitez1802)
|
||||
- [#34620](https://github.com/apache/superset/pull/34620) fix: Use labels in Drill to Detail (@Vitor-Avila)
|
||||
- [#34636](https://github.com/apache/superset/pull/34636) fix(DatabaseModal): Don't set activeKey to undefined repeatedly (@msyavuz)
|
||||
- [#33843](https://github.com/apache/superset/pull/33843) fix: Reset description height to zero when chart is not expanded (@abhinav-1305)
|
||||
- [#34239](https://github.com/apache/superset/pull/34239) fix(Heatmap): addin x axis label rotation (@SBIN2010)
|
||||
- [#34598](https://github.com/apache/superset/pull/34598) fix(db_engine_specs): generate correct boolean filter SQL syntax for Athena compatibility (@oscep)
|
||||
- [#34582](https://github.com/apache/superset/pull/34582) fix(Timeshift): Determine temporal column correctly (@msyavuz)
|
||||
- [#34175](https://github.com/apache/superset/pull/34175) fix(Table chart): fix percentage metric column (@LevisNgigi)
|
||||
- [#34508](https://github.com/apache/superset/pull/34508) fix: update copy text for better capitalization and abbreviation standards (@yousoph)
|
||||
- [#34507](https://github.com/apache/superset/pull/34507) fix(theming): More theming bugs/regressions (@msyavuz)
|
||||
- [#34545](https://github.com/apache/superset/pull/34545) fix: Avoid null `scrollLeft` in `VirtualTable` (@Vitor-Avila)
|
||||
- [#34528](https://github.com/apache/superset/pull/34528) fix(explore): Fix missing await for async buildV1ChartDataPayload calls (@mistercrunch)
|
||||
- [#34512](https://github.com/apache/superset/pull/34512) fix(sqllab): prevent strings with angle brackets from being hidden (@rusackas)
|
||||
- [#34520](https://github.com/apache/superset/pull/34520) fix: docs eslint command (@villebro)
|
||||
- [#34438](https://github.com/apache/superset/pull/34438) fix: Update table chart configuration labels to sentence case (@yousoph)
|
||||
- [#34435](https://github.com/apache/superset/pull/34435) fix(pie chart): Total now positioned correctly with all Legend positions, and respects theming (@rusackas)
|
||||
- [#34436](https://github.com/apache/superset/pull/34436) fix(echarts): resolve bar chart X-axis time formatting stuck on adaptive (@rusackas)
|
||||
- [#34424](https://github.com/apache/superset/pull/34424) fix(theming): Visual bugs p-3 (@msyavuz)
|
||||
- [#34431](https://github.com/apache/superset/pull/34431) fix: time grain and DB dropdowns (@betodealmeida)
|
||||
- [#34137](https://github.com/apache/superset/pull/34137) fix(dashboard): adds dependent filter select first value fixes (@ObservabilityTeam)
|
||||
- [#34433](https://github.com/apache/superset/pull/34433) fix(migrations): prevent theme seeding before themes table exists (@mistercrunch)
|
||||
- [#34412](https://github.com/apache/superset/pull/34412) fix: prevent anonymous code in Postgres (@betodealmeida)
|
||||
- [#31495](https://github.com/apache/superset/pull/31495) fix(sunburst): Fix sunburst chart cross-filter logic (@gerbermichi)
|
||||
- [#34389](https://github.com/apache/superset/pull/34389) fix(theme-list): reorder buttons to place import leftmost (@mistercrunch)
|
||||
- [#34178](https://github.com/apache/superset/pull/34178) fix: Console errors from various sources (@msyavuz)
|
||||
- [#34390](https://github.com/apache/superset/pull/34390) fix(charts): Fix unquoted 'Others' literal in series limit GROUP BY clause (@mistercrunch)
|
||||
- [#34296](https://github.com/apache/superset/pull/34296) fix(big number with trendline): running 2 identical queries for no good reason (@mistercrunch)
|
||||
- [#34381](https://github.com/apache/superset/pull/34381) fix: rate limiting issues with example data hosted on github.com (@mistercrunch)
|
||||
- [#34339](https://github.com/apache/superset/pull/34339) fix: prevent theme initialization errors during fresh installs (@mistercrunch)
|
||||
- [#34360](https://github.com/apache/superset/pull/34360) fix: use catalog name on generated queries (@betodealmeida)
|
||||
- [#34374](https://github.com/apache/superset/pull/34374) fix: subquery alias in RLS (@betodealmeida)
|
||||
- [#34351](https://github.com/apache/superset/pull/34351) fix(PivotTable): Render html in cells if allowRenderHtml is true (@msyavuz)
|
||||
- [#34318](https://github.com/apache/superset/pull/34318) fix(NavBar): Add brand text back (@geido)
|
||||
- [#34268](https://github.com/apache/superset/pull/34268) fix(cartodiagram): add missing locales for rendering echarts (@jansule)
|
||||
- [#34305](https://github.com/apache/superset/pull/34305) fix(npm): more reliable execution of `npm run update-maps` (@rusackas)
|
||||
- [#34300](https://github.com/apache/superset/pull/34300) fix: preserve correct column order when table layout is changed with time comparison enabled (@payose)
|
||||
- [#33084](https://github.com/apache/superset/pull/33084) fix: enhance disallowed SQL functions list for improved security (@sha174n)
|
||||
- [#34303](https://github.com/apache/superset/pull/34303) fix: return 422 on invalid SQL (@betodealmeida)
|
||||
- [#34237](https://github.com/apache/superset/pull/34237) fix(theming): Fix visual regressions from theming P7 (@EnxDev)
|
||||
- [#34299](https://github.com/apache/superset/pull/34299) fix: address numerous long-standing console errors (python & web) (@mistercrunch)
|
||||
- [#34293](https://github.com/apache/superset/pull/34293) fix: Hide View in SQL Lab for users without access (@Vitor-Avila)
|
||||
- [#34233](https://github.com/apache/superset/pull/34233) fix(chart-download): ensure full table or handlebar chart is captured in image export (@fardin-developer)
|
||||
- [#34213](https://github.com/apache/superset/pull/34213) fix(charting): correctly categorize numeric columns with NULL values (@LisaHusband)
|
||||
- [#34235](https://github.com/apache/superset/pull/34235) fix(sqllab_export): manually encode CSV output to support utf-8-sig (@Habeeb556)
|
||||
- [#34275](https://github.com/apache/superset/pull/34275) fix: fix the pre-commit hook for tsc (@mistercrunch)
|
||||
- [#34244](https://github.com/apache/superset/pull/34244) fix(deckgl): fix deck.gl color breakpoints Control (@DamianPendrak)
|
||||
- [#34279](https://github.com/apache/superset/pull/34279) fix(theming): Visual regressions p2 (@msyavuz)
|
||||
- [#34253](https://github.com/apache/superset/pull/34253) fix(theming): Theming visual fixes (@msyavuz)
|
||||
- [#34272](https://github.com/apache/superset/pull/34272) fix: build issues on master with 'npm run dev' (@mistercrunch)
|
||||
- [#34259](https://github.com/apache/superset/pull/34259) fix: Missing ownState and isCached props in Chart.jsx (@kgabryje)
|
||||
- [#34126](https://github.com/apache/superset/pull/34126) fix: database model Collapse state (@SBIN2010)
|
||||
- [#34193](https://github.com/apache/superset/pull/34193) fix: bug when updating dashboard (@SBIN2010)
|
||||
- [#34224](https://github.com/apache/superset/pull/34224) fix(Chart): Calculate chart height correctly (@msyavuz)
|
||||
- [#34229](https://github.com/apache/superset/pull/34229) fix(theming): World map tooltip color (@msyavuz)
|
||||
- [#34199](https://github.com/apache/superset/pull/34199) fix: proper handling of boolean filters with snowflake (@mistercrunch)
|
||||
- [#33933](https://github.com/apache/superset/pull/33933) fix(dashboard): Fix subitem selection on dashboard download menu (@tahvane1)
|
||||
- [#34218](https://github.com/apache/superset/pull/34218) fix(theming): Superset theme configurations correctly applying to charts (@gabotorresruiz)
|
||||
- [#34192](https://github.com/apache/superset/pull/34192) fix: dataset endpoint `/rowlevelsecurity/related/tables` doesn't apply filters as expected (@mistercrunch)
|
||||
- [#33450](https://github.com/apache/superset/pull/33450) fix(chart): update geographical info for latvia (@eriks47)
|
||||
- [#34188](https://github.com/apache/superset/pull/34188) fix(theming): Remove leftover antd5 prefix (@msyavuz)
|
||||
- [#34181](https://github.com/apache/superset/pull/34181) fix(sqllab): database ID (@betodealmeida)
|
||||
- [#34180](https://github.com/apache/superset/pull/34180) fix(databricks): string escaper (@betodealmeida)
|
||||
- [#33955](https://github.com/apache/superset/pull/33955) fix(sqllab): pass DB id instead of name (@betodealmeida)
|
||||
- [#34171](https://github.com/apache/superset/pull/34171) fix(DrillBy): make drill by work with multi metric charts (@msyavuz)
|
||||
- [#34147](https://github.com/apache/superset/pull/34147) fix: adding and removing tags does not work in control panel properties modal (@SBIN2010)
|
||||
- [#34118](https://github.com/apache/superset/pull/34118) fix: frontend translation framework crashes on string errors (@mistercrunch)
|
||||
- [#34153](https://github.com/apache/superset/pull/34153) fix(dataset): trigger `onChange` when switching to physical dataset to clear SQL (@ongdisheng)
|
||||
- [#34112](https://github.com/apache/superset/pull/34112) fix(DatabaseModal): Resolve Connect button issue for SQLAlchemy URI database connections (@EnxDev)
|
||||
- [#34127](https://github.com/apache/superset/pull/34127) fix: Apply metric d3format when currency config is {} for table charts (@Vitor-Avila)
|
||||
- [#33974](https://github.com/apache/superset/pull/33974) fix(i18n): Update Japanese translations (@aikawa-ohno)
|
||||
- [#34114](https://github.com/apache/superset/pull/34114) fix(screenshots): Change default for `SCREENSHOT_PLAYWRIGHT_WAIT_EVENT` to `domcontentloaded` (@rusackas)
|
||||
- [#34115](https://github.com/apache/superset/pull/34115) fix: make flask-cors a core dependency (@mistercrunch)
|
||||
- [#34108](https://github.com/apache/superset/pull/34108) fix: improve login page placement and width (@mistercrunch)
|
||||
- [#34113](https://github.com/apache/superset/pull/34113) fix(UI): Adjust background color for Dashboard, Tabs, and ListView component (@EnxDev)
|
||||
- [#32734](https://github.com/apache/superset/pull/32734) fix: upload data model Collapse state (@SBIN2010)
|
||||
- [#34103](https://github.com/apache/superset/pull/34103) fix(deps): Revert "chore(deps): update @deck.gl/aggregation-layers requirement from ^9.0.38 to ^9.1.12 in /superset-frontend/plugins/legacy-preset-chart-deckgl" (@DamianPendrak)
|
||||
- [#34098](https://github.com/apache/superset/pull/34098) fix: Apply metric d3format from dataset when currency config is {} (@Vitor-Avila)
|
||||
- [#34049](https://github.com/apache/superset/pull/34049) fix(translations): Fix language switching behavior when default language is not English (@PolinaFam)
|
||||
- [#34090](https://github.com/apache/superset/pull/34090) fix(deps) : Revert "chore(deps-dev): bump webpack-dev-server from 4.15.2 to 5.2.1 (@msyavuz)
|
||||
- [#34080](https://github.com/apache/superset/pull/34080) fix: Support metric currency as dict during import (@Vitor-Avila)
|
||||
- [#34014](https://github.com/apache/superset/pull/34014) fix(Table): Allow timeshifts to be overriden (@msyavuz)
|
||||
- [#34066](https://github.com/apache/superset/pull/34066) fix(styles): Remove custom z-indexes (@msyavuz)
|
||||
- [#33954](https://github.com/apache/superset/pull/33954) fix(chart controls): remove duplicated descriptions for chart controls (@Quatters)
|
||||
- [#34031](https://github.com/apache/superset/pull/34031) fix(styling): various minor visual tweaks and adjustments (@mistercrunch)
|
||||
- [#33971](https://github.com/apache/superset/pull/33971) fix(dashboard): prevent crash on invalid CSS selectors in CSS templates (@HarshithGamini)
|
||||
- [#33958](https://github.com/apache/superset/pull/33958) fix: Dashboard native filter fixes (@Vitor-Avila)
|
||||
- [#34016](https://github.com/apache/superset/pull/34016) fix(handlebars): remove serverPaginationControlSetRow from control pa… (@LisaHusband)
|
||||
- [#33977](https://github.com/apache/superset/pull/33977) fix(explore): Change dataset icon on explore to match datasets view (@xavier-GitHub76)
|
||||
- [#33949](https://github.com/apache/superset/pull/33949) fix: Theme logo links to external superset site (@martimors)
|
||||
- [#33939](https://github.com/apache/superset/pull/33939) fix(dremio): apply same fix as for drill to solve alias ambiguity (@mistercrunch)
|
||||
- [#33942](https://github.com/apache/superset/pull/33942) fix(rls): removing unnecessary wrapper (@lohart13)
|
||||
- [#32849](https://github.com/apache/superset/pull/32849) fix(plugin-chart-echarts): correct label position for Negative Values bar chart (@SBIN2010)
|
||||
- [#32857](https://github.com/apache/superset/pull/32857) fix: add suffix to Drill labels to avoid collision (@fhyy)
|
||||
- [#33916](https://github.com/apache/superset/pull/33916) fix: Consider default catalog when getting tables and view lists (@Vitor-Avila)
|
||||
- [#33923](https://github.com/apache/superset/pull/33923) fix(fe/user_info): resolve visual oddities in User Info page (@hainenber)
|
||||
- [#33898](https://github.com/apache/superset/pull/33898) fix(theming): Fix visual regressions from theming P6 (@EnxDev)
|
||||
- [#33846](https://github.com/apache/superset/pull/33846) fix: Correct state handling in CSS Template modal (@abhinav-1305)
|
||||
- [#33826](https://github.com/apache/superset/pull/33826) fix(DatabaseModal): Improve database modal validation and fix visual Issues (@EnxDev)
|
||||
- [#33834](https://github.com/apache/superset/pull/33834) fix(native filters): Make the Apply button available after click on Clear All (@Vitor-Avila)
|
||||
- [#33833](https://github.com/apache/superset/pull/33833) fix(api): Added uuid as a valid search column (@withnale)
|
||||
- [#33867](https://github.com/apache/superset/pull/33867) fix(logo): fix logo url typo (@LevisNgigi)
|
||||
- [#33849](https://github.com/apache/superset/pull/33849) fix: sqlglot linter (@betodealmeida)
|
||||
- [#33764](https://github.com/apache/superset/pull/33764) fix: use risingwave as the sqlalchemy_uri_placeholder prefix for RisingWave engine (@hzxa21)
|
||||
- [#33830](https://github.com/apache/superset/pull/33830) fix: Consider last data point for Big Number comparison lag (@Vitor-Avila)
|
||||
- [#33821](https://github.com/apache/superset/pull/33821) fix: Set time filter's isExtra to false when saving as new chart (@Vitor-Avila)
|
||||
- [#28737](https://github.com/apache/superset/pull/28737) fix: ensure numeric values for extra metadata_cache_timeout payloads (@kidusmakonnen)
|
||||
- [#33763](https://github.com/apache/superset/pull/33763) fix: select star (@betodealmeida)
|
||||
- [#33673](https://github.com/apache/superset/pull/33673) fix: clarify GUEST_TOKEN_JWT_AUDIENCE usage in the SDK (@schollz)
|
||||
- [#33694](https://github.com/apache/superset/pull/33694) fix(chart): set tab name as chart name (@anthonyhungnguyen)
|
||||
- [#33727](https://github.com/apache/superset/pull/33727) fix: typo in SQL dialect map (@betodealmeida)
|
||||
- [#33700](https://github.com/apache/superset/pull/33700) fix(compose): environment entries in compose*.yml override values in docker/.env (@denodo-research-labs)
|
||||
- [#33693](https://github.com/apache/superset/pull/33693) fix: Do not convert dataset changed_on to UTC (@Vitor-Avila)
|
||||
- [#33679](https://github.com/apache/superset/pull/33679) fix: optimize catalog permission sync when importing dashboards (@arafoperata)
|
||||
- [#33626](https://github.com/apache/superset/pull/33626) fix: Update dataset's last modified date from column/metric update (@Vitor-Avila)
|
||||
- [#33195](https://github.com/apache/superset/pull/33195) fix(sqllab): save datasets with template parameters (@ethan-l-geotab)
|
||||
- [#33577](https://github.com/apache/superset/pull/33577) fix(Security): Apply permissions to the AllEntities list/get_objects API endpoint (@Vitor-Avila)
|
||||
- [#33519](https://github.com/apache/superset/pull/33519) fix: add query identifier to legend items in mixed time series charts (@fardin-developer)
|
||||
- [#33407](https://github.com/apache/superset/pull/33407) fix(big number with trendline): add None option to the aggregation method dropdown (@LevisNgigi)
|
||||
- [#33586](https://github.com/apache/superset/pull/33586) fix: correct typos (@castodius)
|
||||
- [#33559](https://github.com/apache/superset/pull/33559) fix(Radar): Radar chart normalisation (@amaannawab923)
|
||||
- [#33516](https://github.com/apache/superset/pull/33516) fix: text => JSON migration util (@betodealmeida)
|
||||
- [#33543](https://github.com/apache/superset/pull/33543) fix(Select): Add buttonStyle prop for backward compatibility (@geido)
|
||||
- [#33521](https://github.com/apache/superset/pull/33521) fix(CI): adding explicit allowable licenses for python dependencies (@rusackas)
|
||||
- [#33501](https://github.com/apache/superset/pull/33501) fix: optimize Explore popovers rendering (@mistercrunch)
|
||||
- [#33494](https://github.com/apache/superset/pull/33494) fix(table): table ui fixes (@amaannawab923)
|
||||
- [#33475](https://github.com/apache/superset/pull/33475) fix(dependabot): adds required schedule to uv updates (@rusackas)
|
||||
- [#33467](https://github.com/apache/superset/pull/33467) fix(NativeFilters): Apply existing values (@geido)
|
||||
- [#33412](https://github.com/apache/superset/pull/33412) fix: loading examples in CI returns http error "too many requests" (@mistercrunch)
|
||||
- [#33356](https://github.com/apache/superset/pull/33356) fix(embedded): handle SUPERSET_APP_ROOT in embedded dashboard URLs (@irodriguez-nebustream)
|
||||
- [#33384](https://github.com/apache/superset/pull/33384) fix: Persist catalog change during dataset update + validation fixes (@Vitor-Avila)
|
||||
- [#33271](https://github.com/apache/superset/pull/33271) fix: Exclude Filter Values (@amaannawab923)
|
||||
- [#33363](https://github.com/apache/superset/pull/33363) fix: bump FAB to 4.6.3 (@dpgaspar)
|
||||
- [#33338](https://github.com/apache/superset/pull/33338) fix: show only filterable columns on filter dropdown (@betodealmeida)
|
||||
- [#33254](https://github.com/apache/superset/pull/33254) fix: `Unexpected input(s) 'depth'` CI warnings (@hamirmahal)
|
||||
- [#33196](https://github.com/apache/superset/pull/33196) fix(chart): Restore subheader used in bignumber with trendline (@LevisNgigi)
|
||||
- [#33205](https://github.com/apache/superset/pull/33205) fix(Native Filters): Keep default filter values when configuring creatable behavior (@geido)
|
||||
- [#33205](https://github.com/apache/superset/pull/33205) fix(Native Filters): Keep default filter values when configuring creatable behavior (@geido)
|
||||
- [#33172](https://github.com/apache/superset/pull/33172) fix: subheader should show as subtitle (@eschutho)
|
||||
- [#33142](https://github.com/apache/superset/pull/33142) fix: add folders to import schema (@eschutho)
|
||||
- [#33141](https://github.com/apache/superset/pull/33141) fix: app icon should not use subdirectory (@eschutho)
|
||||
- [#33126](https://github.com/apache/superset/pull/33126) fix(plugin-chart-table): Don't render redundant items in column config when time comparison is enabled (@kgabryje)
|
||||
- [#33124](https://github.com/apache/superset/pull/33124) fix: `master` builds are failing while trying to push report to cypress (@mistercrunch)
|
||||
- [#33100](https://github.com/apache/superset/pull/33100) fix(OAuth2): Update connection should not fail if connection is missing OAuth2 token (@Vitor-Avila)
|
||||
- [#33114](https://github.com/apache/superset/pull/33114) fix: Broken menu links to datasets and sql lab (@kgabryje)
|
||||
- [#33092](https://github.com/apache/superset/pull/33092) fix: CI file change detector to handle large PRs (@mistercrunch)
|
||||
- [#33095](https://github.com/apache/superset/pull/33095) fix: Broken Python tests on master after merging prefix branch (@martyngigg)
|
||||
- [#33063](https://github.com/apache/superset/pull/33063) fix(docs): Update quickstart.mdx to reflect latest version tag (@clayheaton)
|
||||
- [#33060](https://github.com/apache/superset/pull/33060) fix(list roles): dont send invalid querystrings (@landryb)
|
||||
- [#32990](https://github.com/apache/superset/pull/32990) fix(frontend): add missing antd-5 icon to import (@trentlavoie)
|
||||
- [#32866](https://github.com/apache/superset/pull/32866) fix: make packages PEP 625 compliant (@sadpandajoe)
|
||||
- [#32848](https://github.com/apache/superset/pull/32848) fix: Bump FAB to 4.6.1 (@michael-s-molina)
|
||||
- [#32801](https://github.com/apache/superset/pull/32801) fix(docs): scrollable table of content right bar in Superset docs (@hainenber)
|
||||
- [#32732](https://github.com/apache/superset/pull/32732) fix(asf): Revert "Revert "fix(asf): moving notifications to the top of `.asf.yaml`"" (@rusackas)
|
||||
- [#32730](https://github.com/apache/superset/pull/32730) fix(asf): Revert "fix(asf): moving notifications to the top of `.asf.yaml`" (@rusackas)
|
||||
- [#32728](https://github.com/apache/superset/pull/32728) fix(docs): Another CSP hole for run.app to allow Kapa AI (@rusackas)
|
||||
- [#32727](https://github.com/apache/superset/pull/32727) fix(docs): poking ANOTHER hole in the CSP for the AI bot. (@rusackas)
|
||||
- [#32726](https://github.com/apache/superset/pull/32726) fix(asf): moving notifications to the top of `.asf.yaml` (@rusackas)
|
||||
- [#32724](https://github.com/apache/superset/pull/32724) fix(docs): allow recaptcha in CSP (@rusackas)
|
||||
- [#32713](https://github.com/apache/superset/pull/32713) fix(docs): Fixes scrolling issue with AI widget on docs site (@rusackas)
|
||||
- [#32703](https://github.com/apache/superset/pull/32703) fix(repo): re-enable GitHub Discussions (@rusackas)
|
||||
- [#32704](https://github.com/apache/superset/pull/32704) fix(docs): poking a CSP hole for Kapa AI widget (@rusackas)
|
||||
- [#32571](https://github.com/apache/superset/pull/32571) fix(no-restricted-imports): Fix overrides and include no-fa-icons-usage (@geido)
|
||||
- [#32658](https://github.com/apache/superset/pull/32658) fix(sync perms): Avoid UnboundLocalError during perm sync for DBs that don't support catalogs (@Vitor-Avila)
|
||||
- [#32381](https://github.com/apache/superset/pull/32381) fix(sqllab): Grid header menu (@justinpark)
|
||||
- [#32553](https://github.com/apache/superset/pull/32553) fix(comp/async-ace-editor): proper import of `ace-builds` (@hainenber)
|
||||
- [#32525](https://github.com/apache/superset/pull/32525) fix: always extract query source from request (@villebro)
|
||||
- [#32481](https://github.com/apache/superset/pull/32481) fix(docker compose): replace port 8088 with 9000 (@jpchev)
|
||||
- [#32401](https://github.com/apache/superset/pull/32401) fix: prevent nested transactions (@betodealmeida)
|
||||
- [#32377](https://github.com/apache/superset/pull/32377) fix: ephemeral CI fetching task ENI (@dpgaspar)
|
||||
- [#32333](https://github.com/apache/superset/pull/32333) fix(eslint-hook): ensure eslint hook receives arguments (@alveifbklsiu259)
|
||||
- [#32274](https://github.com/apache/superset/pull/32274) fix(sec): resolve Dependabot security alerts (@hainenber)
|
||||
- [#32018](https://github.com/apache/superset/pull/32018) fix: false negative on critical security related to eslint-plugin-translation-vars (@mistercrunch)
|
||||
|
||||
**Others**
|
||||
|
||||
- [#34693](https://github.com/apache/superset/pull/34693) chore(deps): downgrade pyarrow to v16 (@drummerwolli)
|
||||
- [#34701](https://github.com/apache/superset/pull/34701) docs: CVEs added to 5.0.0 and 4.1.3 documentation (@sha174n)
|
||||
- [#34606](https://github.com/apache/superset/pull/34606) refactor: Migrate ExploreChartPanel to typescript (@justinpark)
|
||||
- [#32663](https://github.com/apache/superset/pull/32663) chore: add more csv tests (@eschutho)
|
||||
- [#34653](https://github.com/apache/superset/pull/34653) chore: Increase memory limit on webpack ts checker plugin (@kgabryje)
|
||||
- [#34460](https://github.com/apache/superset/pull/34460) chore(deps-dev): bump eslint-import-resolver-typescript from 3.7.0 to 4.4.4 in /superset-frontend (@dependabot[bot])
|
||||
- [#34581](https://github.com/apache/superset/pull/34581) chore(deps): bump tmp from 0.2.1 to 0.2.4 in /superset-frontend/cypress-base (@dependabot[bot])
|
||||
- [#34646](https://github.com/apache/superset/pull/34646) chore(deps): bump tmp and inquirer in /superset-frontend (@dependabot[bot])
|
||||
- [#34536](https://github.com/apache/superset/pull/34536) chore: Refactor Menu.Item and cleanup console errors (@geido)
|
||||
- [#34481](https://github.com/apache/superset/pull/34481) chore(deps): bump googleapis from 130.0.0 to 154.1.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#34442](https://github.com/apache/superset/pull/34442) chore: add tests to DatabaseConnectionForm/EncryptedField (@sadpandajoe)
|
||||
- [#34450](https://github.com/apache/superset/pull/34450) chore(deps): bump ws and @types/ws in /superset-websocket (@dependabot[bot])
|
||||
- [#34448](https://github.com/apache/superset/pull/34448) chore(deps-dev): bump @types/node from 22.10.3 to 24.1.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#33889](https://github.com/apache/superset/pull/33889) chore(helm): bump app version to 5.0.0 (@brandon-kaplan)
|
||||
- [#34452](https://github.com/apache/superset/pull/34452) chore(deps-dev): bump globals from 16.0.0 to 16.3.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#34453](https://github.com/apache/superset/pull/34453) chore(deps): update re-resizable requirement from ^6.10.1 to ^6.11.2 in /superset-frontend/packages/superset-ui-core (@dependabot[bot])
|
||||
- [#34468](https://github.com/apache/superset/pull/34468) chore(deps): update @deck.gl/aggregation-layers requirement from ^9.1.13 to ^9.1.14 in /superset-frontend/plugins/legacy-preset-chart-deckgl (@dependabot[bot])
|
||||
- [#34464](https://github.com/apache/superset/pull/34464) chore(deps-dev): bump @babel/runtime-corejs3 from 7.26.7 to 7.28.2 in /superset-frontend (@dependabot[bot])
|
||||
- [#34462](https://github.com/apache/superset/pull/34462) chore(deps-dev): update jest requirement from ^30.0.4 to ^30.0.5 in /superset-frontend/plugins/plugin-chart-pivot-table (@dependabot[bot])
|
||||
- [#34451](https://github.com/apache/superset/pull/34451) chore(deps-dev): update @types/prop-types requirement from ^15.7.2 to ^15.7.15 in /superset-frontend/packages/superset-ui-core (@dependabot[bot])
|
||||
- [#34457](https://github.com/apache/superset/pull/34457) chore(deps-dev): update jest requirement from ^30.0.4 to ^30.0.5 in /superset-frontend/packages/generator-superset (@dependabot[bot])
|
||||
- [#34461](https://github.com/apache/superset/pull/34461) chore(deps): bump @deck.gl/react from 9.1.13 to 9.1.14 in /superset-frontend (@dependabot[bot])
|
||||
- [#34501](https://github.com/apache/superset/pull/34501) chore(deps-dev): update jest requirement from ^30.0.4 to ^30.0.5 in /superset-frontend/plugins/plugin-chart-handlebars (@dependabot[bot])
|
||||
- [#34472](https://github.com/apache/superset/pull/34472) chore(deps): bump @babel/runtime from 7.26.10 to 7.28.2 in /superset-frontend (@dependabot[bot])
|
||||
- [#34454](https://github.com/apache/superset/pull/34454) chore(deps-dev): bump eslint-config-prettier from 10.1.5 to 10.1.8 in /superset-websocket (@dependabot[bot])
|
||||
- [#34474](https://github.com/apache/superset/pull/34474) chore(deps): bump react-draggable from 4.4.6 to 4.5.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#34483](https://github.com/apache/superset/pull/34483) chore(deps): bump react-lines-ellipsis from 0.15.4 to 0.16.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#34492](https://github.com/apache/superset/pull/34492) chore(deps-dev): bump eslint from 9.31.0 to 9.32.0 in /docs (@dependabot[bot])
|
||||
- [#34493](https://github.com/apache/superset/pull/34493) chore(deps-dev): bump typescript-eslint from 8.37.0 to 8.38.0 in /docs (@dependabot[bot])
|
||||
- [#34502](https://github.com/apache/superset/pull/34502) chore(deps): update react requirement from ^19.1.0 to ^19.1.1 in /superset-frontend/plugins/legacy-plugin-chart-chord (@dependabot[bot])
|
||||
- [#34487](https://github.com/apache/superset/pull/34487) chore(deps): bump @rjsf/validator-ajv8 from 5.24.9 to 5.24.12 in /superset-frontend (@dependabot[bot])
|
||||
- [#34489](https://github.com/apache/superset/pull/34489) chore(deps-dev): bump @babel/preset-react from 7.26.3 to 7.27.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#34496](https://github.com/apache/superset/pull/34496) chore(deps-dev): bump eslint-plugin-prettier from 5.5.1 to 5.5.3 in /docs (@dependabot[bot])
|
||||
- [#34544](https://github.com/apache/superset/pull/34544) chore: Rename dataset creation buttons (@Vitor-Avila)
|
||||
- [#34515](https://github.com/apache/superset/pull/34515) chore(core): Add drawer to core ui components (@justinpark)
|
||||
- [#34444](https://github.com/apache/superset/pull/34444) chore(deps): update gh-pages requirement from ^6.2.0 to ^6.3.0 in /superset-frontend/packages/superset-ui-demo (@dependabot[bot])
|
||||
- [#34478](https://github.com/apache/superset/pull/34478) chore(deps-dev): bump @types/classnames from 2.3.0 to 2.3.4 in /superset-frontend (@dependabot[bot])
|
||||
- [#34482](https://github.com/apache/superset/pull/34482) chore(deps): bump dom-to-image-more from 3.5.0 to 3.6.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#34480](https://github.com/apache/superset/pull/34480) chore(deps): bump @deck.gl/core from 9.1.13 to 9.1.14 in /superset-frontend (@dependabot[bot])
|
||||
- [#34484](https://github.com/apache/superset/pull/34484) chore(deps-dev): bump tsx from 4.19.4 to 4.20.3 in /superset-frontend (@dependabot[bot])
|
||||
- [#34485](https://github.com/apache/superset/pull/34485) chore(deps-dev): bump @babel/compat-data from 7.27.2 to 7.28.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#34494](https://github.com/apache/superset/pull/34494) chore(deps): bump less from 4.3.0 to 4.4.0 in /docs (@dependabot[bot])
|
||||
- [#34495](https://github.com/apache/superset/pull/34495) chore(deps): bump antd from 5.26.3 to 5.26.7 in /docs (@dependabot[bot])
|
||||
- [#34497](https://github.com/apache/superset/pull/34497) chore(deps-dev): bump @eslint/js from 9.31.0 to 9.32.0 in /docs (@dependabot[bot])
|
||||
- [#34498](https://github.com/apache/superset/pull/34498) chore(deps): bump swagger-ui-react from 5.26.0 to 5.27.1 in /docs (@dependabot[bot])
|
||||
- [#34499](https://github.com/apache/superset/pull/34499) chore(deps-dev): bump eslint-config-prettier from 10.1.5 to 10.1.8 in /docs (@dependabot[bot])
|
||||
- [#34500](https://github.com/apache/superset/pull/34500) chore(deps-dev): bump webpack from 5.99.9 to 5.101.0 in /docs (@dependabot[bot])
|
||||
- [#34459](https://github.com/apache/superset/pull/34459) chore(deps): bump actions/first-interaction from 1 to 2 (@dependabot[bot])
|
||||
- [#34393](https://github.com/apache/superset/pull/34393) chore: update chart list e2e and component tests (@sadpandajoe)
|
||||
- [#34039](https://github.com/apache/superset/pull/34039) chore(deps-dev): update jest requirement from ^30.0.2 to ^30.0.4 in /superset-frontend/packages/generator-superset (@dependabot[bot])
|
||||
- [#34432](https://github.com/apache/superset/pull/34432) chore: Change button labels to sentence case (@kasiazjc)
|
||||
- [#34429](https://github.com/apache/superset/pull/34429) chore: Add bottom border to top navigation menu (@kasiazjc)
|
||||
- [#30119](https://github.com/apache/superset/pull/30119) build(deps): bump reselect from 4.1.7 to 5.1.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#31534](https://github.com/apache/superset/pull/31534) chore(deps): bump d3-scale from 3.3.0 to 4.0.2 in /superset-frontend/packages/superset-ui-core (@dependabot[bot])
|
||||
- [#34391](https://github.com/apache/superset/pull/34391) docs(development): fix comment in the dockerfile (@harikirank)
|
||||
- [#34387](https://github.com/apache/superset/pull/34387) docs(development): fix typo in the dockerfile (@harikirank)
|
||||
- [#34335](https://github.com/apache/superset/pull/34335) chore(deps): bump cookie and @types/cookie in /superset-websocket (@dependabot[bot])
|
||||
- [#34326](https://github.com/apache/superset/pull/34326) build(deps): update `ag-grid` to non-breaking major v34 (@hainenber)
|
||||
- [#34341](https://github.com/apache/superset/pull/34341) docs(development): fix 2 typos in the dockerfile (@harikirank)
|
||||
- [#34371](https://github.com/apache/superset/pull/34371) chore: bump BigQuery dialect to 1.15.0 (@betodealmeida)
|
||||
- [#34317](https://github.com/apache/superset/pull/34317) style(FastVizSwitcher): Adjust padding for FastVizSwitcher selector (@EnxDev)
|
||||
- [#34311](https://github.com/apache/superset/pull/34311) style(chart): restyle table pagination (@imcewen02)
|
||||
- [#34302](https://github.com/apache/superset/pull/34302) chore: bump sqlglot to latest version (27.3.0) (@betodealmeida)
|
||||
- [#34270](https://github.com/apache/superset/pull/34270) chore: improve sqlglot parsing (@betodealmeida)
|
||||
- [#34288](https://github.com/apache/superset/pull/34288) chore: remove supposedly dev dep `html-webpack-plugin` from lockfile (@hainenber)
|
||||
- [#33997](https://github.com/apache/superset/pull/33997) chore(deps-dev): bump prettier from 3.5.3 to 3.6.2 in /superset-frontend (@dependabot[bot])
|
||||
- [#34285](https://github.com/apache/superset/pull/34285) chore(deps): bump axios from 1.10.0 to 1.11.0 in /docs (@dependabot[bot])
|
||||
- [#34067](https://github.com/apache/superset/pull/34067) style(Button): Vertically align icons across all buttons (@EnxDev)
|
||||
- [#34146](https://github.com/apache/superset/pull/34146) chore(docker): use editable mode in docker images (@mistercrunch)
|
||||
- [#34262](https://github.com/apache/superset/pull/34262) chore(deps-dev): bump form-data from 4.0.0 to 4.0.4 in /superset-embedded-sdk (@dependabot[bot])
|
||||
- [#34263](https://github.com/apache/superset/pull/34263) chore(deps): bump form-data from 4.0.0 to 4.0.4 in /docs (@dependabot[bot])
|
||||
- [#34265](https://github.com/apache/superset/pull/34265) chore(deps): bump form-data from 4.0.1 to 4.0.4 in /superset-frontend (@dependabot[bot])
|
||||
- [#34215](https://github.com/apache/superset/pull/34215) chore(deps): bump on-headers and morgan in /superset-websocket/utils/client-ws-app (@dependabot[bot])
|
||||
- [#34216](https://github.com/apache/superset/pull/34216) chore(deps): bump on-headers and compression in /superset-frontend (@dependabot[bot])
|
||||
- [#34217](https://github.com/apache/superset/pull/34217) chore: Updates files related to 4.1.3 release (@sadpandajoe)
|
||||
- [#33736](https://github.com/apache/superset/pull/33736) style(helm): Minor reformatting of helm chart templates (@dnskr)
|
||||
- [#34179](https://github.com/apache/superset/pull/34179) chore(Oracle): Update oracle column length to 128 (@msyavuz)
|
||||
- [#34163](https://github.com/apache/superset/pull/34163) docs(development): Fix typo in the documentation (@harikirank)
|
||||
- [#34149](https://github.com/apache/superset/pull/34149) chore(Tags): Sort tags by name if possible (@msyavuz)
|
||||
- [#34145](https://github.com/apache/superset/pull/34145) docs: remove duplicated line in `Running tests with act` section (@ongdisheng)
|
||||
- [#34125](https://github.com/apache/superset/pull/34125) build(dev-deps): clean up deprecated Babel proposal plugins (@hainenber)
|
||||
- [#34138](https://github.com/apache/superset/pull/34138) chore(deps): bump flask-cors from 4.0.2 to 6.0.0 (@dependabot[bot])
|
||||
- [#34139](https://github.com/apache/superset/pull/34139) chore: remove unnecessary disables (@betodealmeida)
|
||||
- [#33990](https://github.com/apache/superset/pull/33990) chore(deps): bump react-json-tree from 0.17.0 to 0.20.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#33486](https://github.com/apache/superset/pull/33486) chore(deps): bump react-error-boundary from 5.0.0 to 6.0.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#34093](https://github.com/apache/superset/pull/34093) chore: clean up more flask/jinja html views (@mistercrunch)
|
||||
- [#34097](https://github.com/apache/superset/pull/34097) chore: Improve performance to load chart's save modal (@Vitor-Avila)
|
||||
- [#34079](https://github.com/apache/superset/pull/34079) chore: Improve performance to load the chart properties modal (@Vitor-Avila)
|
||||
- [#34104](https://github.com/apache/superset/pull/34104) chore(deps-dev): bump webpack-dev-server from 4.15.2 to 5.2.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#34057](https://github.com/apache/superset/pull/34057) chore: move auth e2e tests to component tests (@sadpandajoe)
|
||||
- [#34042](https://github.com/apache/superset/pull/34042) chore(deps): bump @fontsource/inter from 5.1.1 to 5.2.6 in /superset-frontend (@dependabot[bot])
|
||||
- [#34029](https://github.com/apache/superset/pull/34029) chore(deps): bump ioredis from 4.28.5 to 5.6.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#34075](https://github.com/apache/superset/pull/34075) chore: Use select_columns on chart's dashboard filter (@Vitor-Avila)
|
||||
- [#34028](https://github.com/apache/superset/pull/34028) chore: refactor react-syntax-highlither to handle dark themes (@mistercrunch)
|
||||
- [#34056](https://github.com/apache/superset/pull/34056) chore: remove some of the deprecated theme.colors.* (@mistercrunch)
|
||||
- [#34059](https://github.com/apache/superset/pull/34059) chore(deps): bump tar-fs from 2.1.2 to 3.1.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#32928](https://github.com/apache/superset/pull/32928) chore(deps): update yeoman-generator requirement from ^7.4.0 to ^7.5.1 in /superset-frontend/packages/generator-superset (@dependabot[bot])
|
||||
- [#32949](https://github.com/apache/superset/pull/32949) chore(deps): bump react from 17.0.2 to 19.1.0 in /superset-frontend/plugins/legacy-plugin-chart-chord (@dependabot[bot])
|
||||
- [#33481](https://github.com/apache/superset/pull/33481) chore(deps-dev): update fork-ts-checker-webpack-plugin requirement from ^9.0.2 to ^9.1.0 in /superset-frontend/packages/superset-ui-demo (@dependabot[bot])
|
||||
- [#33485](https://github.com/apache/superset/pull/33485) chore(deps): update @deck.gl/aggregation-layers requirement from ^9.0.38 to ^9.1.12 in /superset-frontend/plugins/legacy-preset-chart-deckgl (@dependabot[bot])
|
||||
- [#32946](https://github.com/apache/superset/pull/32946) chore(deps-dev): bump webpack-dev-server from 4.15.2 to 5.2.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#33986](https://github.com/apache/superset/pull/33986) chore(deps-dev): bump @types/jest from 29.5.14 to 30.0.0 in /superset-frontend/plugins/plugin-chart-handlebars (@dependabot[bot])
|
||||
- [#33496](https://github.com/apache/superset/pull/33496) chore(deps-dev): bump yeoman-test from 8.3.0 to 10.1.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#33995](https://github.com/apache/superset/pull/33995) chore(deps): bump @storybook/addon-actions from 8.1.11 to 9.0.8 in /superset-frontend/packages/superset-ui-demo (@dependabot[bot])
|
||||
- [#32441](https://github.com/apache/superset/pull/32441) chore(deps): update @types/d3-scale requirement from ^4.0.8 to ^4.0.9 in /superset-frontend/plugins/plugin-chart-word-cloud (@dependabot[bot])
|
||||
- [#32082](https://github.com/apache/superset/pull/32082) chore(deps): update dompurify requirement from ^3.2.4 to ^3.2.6 in /superset-frontend/plugins/legacy-preset-chart-nvd3 (@dependabot[bot])
|
||||
- [#32945](https://github.com/apache/superset/pull/32945) chore(deps): bump remark-gfm from 3.0.1 to 4.0.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#32953](https://github.com/apache/superset/pull/32953) chore(deps): bump @ant-design/icons from 5.6.1 to 6.0.0 in /docs (@dependabot[bot])
|
||||
- [#32439](https://github.com/apache/superset/pull/32439) chore(deps-dev): bump typescript from 5.6.2 to 5.7.3 in /superset-websocket (@dependabot[bot])
|
||||
- [#32080](https://github.com/apache/superset/pull/32080) chore(deps-dev): update @types/lodash requirement from ^4.17.16 to ^4.17.20 in /superset-frontend/packages/superset-ui-core (@dependabot[bot])
|
||||
- [#33991](https://github.com/apache/superset/pull/33991) chore(deps-dev): bump cheerio from 1.0.0-rc.10 to 1.1.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#33989](https://github.com/apache/superset/pull/33989) chore(deps-dev): bump webpack-visualizer-plugin2 from 1.1.0 to 1.2.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#32093](https://github.com/apache/superset/pull/32093) chore(deps-dev): update fs-extra requirement from ^11.2.0 to ^11.3.0 in /superset-frontend/packages/generator-superset (@dependabot[bot])
|
||||
- [#32077](https://github.com/apache/superset/pull/32077) chore(deps): update @types/geojson requirement from ^7946.0.15 to ^7946.0.16 in /superset-frontend/plugins/legacy-preset-chart-deckgl (@dependabot[bot])
|
||||
- [#31560](https://github.com/apache/superset/pull/31560) chore(deps): bump @emotion/styled from 11.3.0 to 11.14.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#34034](https://github.com/apache/superset/pull/34034) chore(deps-dev): update jest requirement from ^30.0.2 to ^30.0.4 in /superset-frontend/plugins/plugin-chart-handlebars (@dependabot[bot])
|
||||
- [#34036](https://github.com/apache/superset/pull/34036) chore(deps-dev): update jest requirement from ^30.0.2 to ^30.0.4 in /superset-frontend/plugins/plugin-chart-pivot-table (@dependabot[bot])
|
||||
- [#34037](https://github.com/apache/superset/pull/34037) chore(deps-dev): update @types/lodash requirement from ^4.17.16 to ^4.17.20 in /superset-frontend/plugins/plugin-chart-handlebars (@dependabot[bot])
|
||||
- [#34038](https://github.com/apache/superset/pull/34038) chore(deps-dev): update @babel/types requirement from ^7.26.9 to ^7.28.0 in /superset-frontend/plugins/plugin-chart-pivot-table (@dependabot[bot])
|
||||
- [#34043](https://github.com/apache/superset/pull/34043) chore(deps): bump ace-builds from 1.43.0 to 1.43.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#34008](https://github.com/apache/superset/pull/34008) chore(deps): bump mapbox-gl from 2.15.0 to 3.13.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#34035](https://github.com/apache/superset/pull/34035) chore(deps-dev): bump @types/lodash from 4.17.13 to 4.17.20 in /superset-websocket (@dependabot[bot])
|
||||
- [#33992](https://github.com/apache/superset/pull/33992) chore(deps): bump @emotion/styled from 11.14.0 to 11.14.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#33987](https://github.com/apache/superset/pull/33987) chore(deps-dev): bump @applitools/eyes-storybook from 3.53.4 to 3.55.6 in /superset-frontend (@dependabot[bot])
|
||||
- [#34033](https://github.com/apache/superset/pull/34033) chore(deps-dev): bump prettier from 3.4.2 to 3.6.2 in /superset-websocket (@dependabot[bot])
|
||||
- [#34041](https://github.com/apache/superset/pull/34041) chore(deps): bump swagger-ui-react from 5.25.3 to 5.26.0 in /docs (@dependabot[bot])
|
||||
- [#33979](https://github.com/apache/superset/pull/33979) build(dev-deps): upgrade Jest to major version v30 (@hainenber)
|
||||
- [#34004](https://github.com/apache/superset/pull/34004) chore(deps): bump hot-shots from 10.2.1 to 11.1.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#34003](https://github.com/apache/superset/pull/34003) chore(deps-dev): bump @docusaurus/tsconfig from 3.8.0 to 3.8.1 in /docs (@dependabot[bot])
|
||||
- [#34002](https://github.com/apache/superset/pull/34002) chore(deps): bump ace-builds from 1.41.0 to 1.43.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#34001](https://github.com/apache/superset/pull/34001) chore(deps): bump swagger-ui-react from 5.25.2 to 5.25.3 in /docs (@dependabot[bot])
|
||||
- [#34000](https://github.com/apache/superset/pull/34000) chore(deps-dev): bump eslint from 9.27.0 to 9.30.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#33985](https://github.com/apache/superset/pull/33985) chore(deps-dev): bump @babel/cli from 7.26.4 to 7.27.2 in /superset-frontend (@dependabot[bot])
|
||||
- [#33999](https://github.com/apache/superset/pull/33999) chore(deps): bump actions/cache from 3 to 4 (@dependabot[bot])
|
||||
- [#33982](https://github.com/apache/superset/pull/33982) chore(deps): bump antd from 5.25.1 to 5.26.3 in /docs (@dependabot[bot])
|
||||
- [#33967](https://github.com/apache/superset/pull/33967) chore: replace `querystring` usage with native `URLSearchParams` API (@hainenber)
|
||||
- [#33972](https://github.com/apache/superset/pull/33972) docs: Fix typo in UPDATING.md regarding translations in version 5.0.0 (@hugo19941994)
|
||||
- [#33887](https://github.com/apache/superset/pull/33887) chore(build): refactor plugin build script to remove unused stanzas (@hainenber)
|
||||
- [#32891](https://github.com/apache/superset/pull/32891) docs: pypi-installation on Ubuntu 24.04 and statsd package for event-logging (@125m125)
|
||||
- [#33934](https://github.com/apache/superset/pull/33934) chore(translations): Update FR language (@Eric-Brison)
|
||||
- [#33927](https://github.com/apache/superset/pull/33927) build(be/deps): upgrade `urllib3` to major v2 (@hainenber)
|
||||
- [#33936](https://github.com/apache/superset/pull/33936) docs(security): add Q&A related to CVE scans to FAQ (@sfirke)
|
||||
- [#33910](https://github.com/apache/superset/pull/33910) chore(superset-embedded-sdk): bump version for theming (@msyavuz)
|
||||
- [#33909](https://github.com/apache/superset/pull/33909) style(AsyncAceEditor): make Ace gutter line color theme-aware (@EnxDev)
|
||||
- [#33872](https://github.com/apache/superset/pull/33872) chore(docs): bump references to docker image versions upon release of 5.0.0 (@sfirke)
|
||||
- [#33869](https://github.com/apache/superset/pull/33869) chore: Updates files related to 5.0.0 release (@michael-s-molina)
|
||||
- [#33868](https://github.com/apache/superset/pull/33868) build(be/deps): replace `importlib_metadata` usage with native Python 3.10+ `importlib.metadata` (@hainenber)
|
||||
- [#33854](https://github.com/apache/superset/pull/33854) build(dev-deps): update `fetch-mock` to v11 (@hainenber)
|
||||
- [#33853](https://github.com/apache/superset/pull/33853) build(deps): remove legacy browser polyfills (@hainenber)
|
||||
- [#33866](https://github.com/apache/superset/pull/33866) chore(Icons): Add UsergroupAddOutlined icon (@EnxDev)
|
||||
- [#33850](https://github.com/apache/superset/pull/33850) style(menu): Reduce bottom border width of menu item (@EnxDev)
|
||||
- [#33848](https://github.com/apache/superset/pull/33848) chore: use mysql dialect for Pinot (@betodealmeida)
|
||||
- [#33790](https://github.com/apache/superset/pull/33790) refactor: rename docker-compose files and update references (@polRk)
|
||||
- [#33670](https://github.com/apache/superset/pull/33670) docs: Update STANDARD_ROLES.md, delete 7 permissions "RowLevelSecurityFiltersModelView" (@xavier-GitHub76)
|
||||
- [#33642](https://github.com/apache/superset/pull/33642) chore(deps-dev): bump @docusaurus/module-type-aliases from 3.7.0 to 3.8.0 in /docs (@dependabot[bot])
|
||||
- [#33818](https://github.com/apache/superset/pull/33818) chore(docs): resolve 3 vulnerabilities (@hainenber)
|
||||
- [#33795](https://github.com/apache/superset/pull/33795) chore(🦾): bump python flask-caching subpackage(s) (@github-actions[bot])
|
||||
- [#33798](https://github.com/apache/superset/pull/33798) chore(🦾): bump python sqlglot 26.17.1 -> 26.28.1 (@github-actions[bot])
|
||||
- [#33792](https://github.com/apache/superset/pull/33792) chore(🦾): bump python flask-session subpackage(s) (@github-actions[bot])
|
||||
- [#33793](https://github.com/apache/superset/pull/33793) chore(🦾): bump python shillelagh subpackage(s) (@github-actions[bot])
|
||||
- [#33799](https://github.com/apache/superset/pull/33799) chore(🦾): bump python flask-wtf subpackage(s) (@github-actions[bot])
|
||||
- [#33797](https://github.com/apache/superset/pull/33797) chore(🦾): bump python flask subpackage(s) (@github-actions[bot])
|
||||
- [#33796](https://github.com/apache/superset/pull/33796) chore(🦾): bump python click 8.2.0 -> 8.2.1 (@github-actions[bot])
|
||||
- [#33800](https://github.com/apache/superset/pull/33800) chore(🦾): bump python flask-compress subpackage(s) (@github-actions[bot])
|
||||
- [#32587](https://github.com/apache/superset/pull/32587) refactor(Menu): Use items prop instead of deprecated Menu.Item HOC (@msyavuz)
|
||||
- [#26803](https://github.com/apache/superset/pull/26803) chore: add pylint rule for SQL importing (SIP-117) (@betodealmeida)
|
||||
- [#33396](https://github.com/apache/superset/pull/33396) chore(Accessibility): Improve keyboard navigation and screen access (@geido)
|
||||
- [#33767](https://github.com/apache/superset/pull/33767) chore: auto-focus modal input when deleting assets (@betodealmeida)
|
||||
- [#33696](https://github.com/apache/superset/pull/33696) chore: Convert alert and report cypress tests to component tests (@sadpandajoe)
|
||||
- [#33643](https://github.com/apache/superset/pull/33643) chore(deps-dev): bump webpack from 5.99.8 to 5.99.9 in /docs (@dependabot[bot])
|
||||
- [#33645](https://github.com/apache/superset/pull/33645) chore(deps-dev): bump @docusaurus/tsconfig from 3.7.0 to 3.8.0 in /docs (@dependabot[bot])
|
||||
- [#33650](https://github.com/apache/superset/pull/33650) chore(deps-dev): bump @typescript-eslint/parser from 8.29.0 to 8.33.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#33721](https://github.com/apache/superset/pull/33721) docs: fix typo and improve alt text in README (@lourduradjou)
|
||||
- [#33715](https://github.com/apache/superset/pull/33715) chore: delete remaining Enzyme tests (@mistercrunch)
|
||||
- [#33714](https://github.com/apache/superset/pull/33714) docs: clarify how `requirements/` should be modified (@mistercrunch)
|
||||
- [#33704](https://github.com/apache/superset/pull/33704) chore: remove unused parameter (@betodealmeida)
|
||||
- [#33701](https://github.com/apache/superset/pull/33701) chore: update sqlglot dialect map (@betodealmeida)
|
||||
- [#33661](https://github.com/apache/superset/pull/33661) chore: simplify query cleanup using dict.pop instead of suppressing exception (@dpgaspar)
|
||||
- [#33568](https://github.com/apache/superset/pull/33568) chore: 100% test coverage for SQL parsing (@betodealmeida)
|
||||
- [#33665](https://github.com/apache/superset/pull/33665) docs: add HPE to users list (@anmol-hpe)
|
||||
- [#33662](https://github.com/apache/superset/pull/33662) docs: CVE-2025-48912 added to 4.1.2 (@sha174n)
|
||||
- [#33619](https://github.com/apache/superset/pull/33619) chore: make DB syntax errors 400 (@betodealmeida)
|
||||
- [#33622](https://github.com/apache/superset/pull/33622) chore(deps-dev): bump fastify from 4.29.0 to 4.29.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#33607](https://github.com/apache/superset/pull/33607) chore: bump FAB to 4.7.0 (@dpgaspar)
|
||||
- [#33474](https://github.com/apache/superset/pull/33474) chore: remove parse_sql (@betodealmeida)
|
||||
- [#33515](https://github.com/apache/superset/pull/33515) chore: sql/parse cleanup (@betodealmeida)
|
||||
- [#33567](https://github.com/apache/superset/pull/33567) chore(alerts & reports): increase Playwright timeout from 30 -> 60 seconds (@sfirke)
|
||||
- [#33566](https://github.com/apache/superset/pull/33566) docs(docker build): add more packages needed for production features (@sfirke)
|
||||
- [#33478](https://github.com/apache/superset/pull/33478) chore(deps-dev): bump eslint-config-prettier from 9.1.0 to 10.1.5 in /superset-websocket (@dependabot[bot])
|
||||
- [#33489](https://github.com/apache/superset/pull/33489) chore(deps-dev): bump babel-loader from 9.2.1 to 10.0.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#33488](https://github.com/apache/superset/pull/33488) chore(deps): bump less-loader from 11.1.4 to 12.3.0 in /docs (@dependabot[bot])
|
||||
- [#33477](https://github.com/apache/superset/pull/33477) chore(deps-dev): bump eslint from 9.17.0 to 9.27.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#33457](https://github.com/apache/superset/pull/33457) chore: remove is_select_query (@betodealmeida)
|
||||
- [#33549](https://github.com/apache/superset/pull/33549) chore: remove useless-suppression (@betodealmeida)
|
||||
- [#33539](https://github.com/apache/superset/pull/33539) chore(Icons): Additional Ant Design Icons (@geido)
|
||||
- [#33469](https://github.com/apache/superset/pull/33469) chore(fab): bumped fab from 4.6.3 to 4.6.4 (@alexandrusoare)
|
||||
- [#33498](https://github.com/apache/superset/pull/33498) chore(deps): bump ace-builds from 1.37.5 to 1.41.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#33476](https://github.com/apache/superset/pull/33476) chore(deps): bump debug from 4.4.0 to 4.4.1 in /superset-websocket/utils/client-ws-app (@dependabot[bot])
|
||||
- [#33491](https://github.com/apache/superset/pull/33491) chore(deps-dev): bump eslint-config-prettier from 10.1.2 to 10.1.5 in /docs (@dependabot[bot])
|
||||
- [#33492](https://github.com/apache/superset/pull/33492) chore(deps-dev): bump webpack from 5.99.7 to 5.99.8 in /docs (@dependabot[bot])
|
||||
- [#33490](https://github.com/apache/superset/pull/33490) chore(deps): bump antd from 5.24.9 to 5.25.1 in /docs (@dependabot[bot])
|
||||
- [#33499](https://github.com/apache/superset/pull/33499) chore(deps-dev): bump @babel/preset-env from 7.26.7 to 7.27.2 in /superset-frontend (@dependabot[bot])
|
||||
- [#33458](https://github.com/apache/superset/pull/33458) docs: added europace to INTHEWILD.md (@Bierbarbar)
|
||||
- [#33472](https://github.com/apache/superset/pull/33472) docs(installation): show example of extending Docker image (@sfirke)
|
||||
- [#32948](https://github.com/apache/superset/pull/32948) chore(deps): bump express from 4.21.2 to 5.1.0 in /superset-websocket/utils/client-ws-app (@dependabot[bot])
|
||||
- [#33278](https://github.com/apache/superset/pull/33278) chore(🦾): bump python shillelagh subpackage(s) (@github-actions[bot])
|
||||
- [#33435](https://github.com/apache/superset/pull/33435) docs: CVEs fixed on 4.1.2 (@sha174n)
|
||||
- [#33397](https://github.com/apache/superset/pull/33397) chore: Add missing ECharts tags (@DamianPendrak)
|
||||
- [#30878](https://github.com/apache/superset/pull/30878) docs: fix for role sync issues in case of custom OAuth2 configuration (@ved-kashyap-samsung)
|
||||
- [#33319](https://github.com/apache/superset/pull/33319) chore(deps): bump antd from 5.24.5 to 5.24.9 in /docs (@dependabot[bot])
|
||||
- [#33378](https://github.com/apache/superset/pull/33378) chore: regenerate `openapi.json` (@betodealmeida)
|
||||
- [#33279](https://github.com/apache/superset/pull/33279) chore(🦾): bump python markdown 3.7 -> 3.8 (@github-actions[bot])
|
||||
- [#33370](https://github.com/apache/superset/pull/33370) chore(🦾): bump python sshtunnel subpackage(s) (@github-actions[bot])
|
||||
- [#33371](https://github.com/apache/superset/pull/33371) chore(🦾): bump python cryptography 44.0.2 -> 44.0.3 (@github-actions[bot])
|
||||
- [#33369](https://github.com/apache/superset/pull/33369) chore(🦾): bump python humanize 4.12.2 -> 4.12.3 (@github-actions[bot])
|
||||
- [#33368](https://github.com/apache/superset/pull/33368) chore(🦾): bump python sqlglot 26.16.2 -> 26.16.4 (@github-actions[bot])
|
||||
- [#33318](https://github.com/apache/superset/pull/33318) chore(deps): bump swagger-ui-react from 5.20.2 to 5.21.0 in /docs (@dependabot[bot])
|
||||
- [#33323](https://github.com/apache/superset/pull/33323) chore(deps-dev): update ts-loader requirement from ^9.5.1 to ^9.5.2 in /superset-frontend/packages/superset-ui-demo (@dependabot[bot])
|
||||
- [#33311](https://github.com/apache/superset/pull/33311) chore(deps): bump uuid from 11.0.2 to 11.1.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#33312](https://github.com/apache/superset/pull/33312) chore(deps-dev): bump @eslint/js from 9.17.0 to 9.25.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#33317](https://github.com/apache/superset/pull/33317) chore(deps): bump less from 4.2.2 to 4.3.0 in /docs (@dependabot[bot])
|
||||
- [#33350](https://github.com/apache/superset/pull/33350) docs(docker-builds.mdx): clarify dockerize images (@jdorel)
|
||||
- [#33315](https://github.com/apache/superset/pull/33315) chore(deps-dev): bump eslint-config-prettier from 10.1.1 to 10.1.2 in /docs (@dependabot[bot])
|
||||
- [#33320](https://github.com/apache/superset/pull/33320) chore(deps-dev): bump typescript from 5.8.2 to 5.8.3 in /docs (@dependabot[bot])
|
||||
- [#33314](https://github.com/apache/superset/pull/33314) chore(deps-dev): bump eslint-plugin-react from 7.37.4 to 7.37.5 in /docs (@dependabot[bot])
|
||||
- [#33316](https://github.com/apache/superset/pull/33316) chore(deps-dev): bump webpack from 5.98.0 to 5.99.7 in /docs (@dependabot[bot])
|
||||
- [#33321](https://github.com/apache/superset/pull/33321) chore(deps): bump @rjsf/validator-ajv8 from 5.24.1 to 5.24.9 in /superset-frontend (@dependabot[bot])
|
||||
- [#33332](https://github.com/apache/superset/pull/33332) chore(deps-dev): bump @babel/plugin-transform-runtime from 7.25.9 to 7.27.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#33333](https://github.com/apache/superset/pull/33333) chore(deps): bump react-intersection-observer from 9.15.1 to 9.16.0 in /superset-frontend (@dependabot[bot])
|
||||
- [#31476](https://github.com/apache/superset/pull/31476) chore(deps): Upgrade pyarrow to 18.1.0 (@phillipleblanc)
|
||||
- [#33277](https://github.com/apache/superset/pull/33277) chore(🦾): bump python importlib-metadata 8.6.1 -> 8.7.0 (@github-actions[bot])
|
||||
- [#33280](https://github.com/apache/superset/pull/33280) chore(🦾): bump python mako 1.3.9 -> 1.3.10 (@github-actions[bot])
|
||||
- [#33281](https://github.com/apache/superset/pull/33281) chore(🦾): bump python pyparsing 3.2.2 -> 3.2.3 (@github-actions[bot])
|
||||
- [#33257](https://github.com/apache/superset/pull/33257) chore(🦾): bump python celery 5.4.0 -> 5.5.2 (@github-actions[bot])
|
||||
- [#33259](https://github.com/apache/superset/pull/33259) chore(🦾): bump python packaging 24.2 -> 25.0 (@github-actions[bot])
|
||||
- [#33260](https://github.com/apache/superset/pull/33260) chore(🦾): bump python deprecation subpackage(s) (@github-actions[bot])
|
||||
- [#33262](https://github.com/apache/superset/pull/33262) chore(🦾): bump python python-dotenv 1.0.1 -> 1.1.0 (@github-actions[bot])
|
||||
- [#33263](https://github.com/apache/superset/pull/33263) chore(🦾): bump python pandas subpackage(s) (@github-actions[bot])
|
||||
- [#33266](https://github.com/apache/superset/pull/33266) chore(🦾): bump python sqlglot 26.11.1 -> 26.16.2 (@github-actions[bot])
|
||||
- [#33265](https://github.com/apache/superset/pull/33265) chore(🦾): bump python gunicorn subpackage(s) (@github-actions[bot])
|
||||
- [#33258](https://github.com/apache/superset/pull/33258) chore(🦾): bump python croniter subpackage(s) (@github-actions[bot])
|
||||
- [#33236](https://github.com/apache/superset/pull/33236) chore: add some utils tests (@eschutho)
|
||||
- [#33137](https://github.com/apache/superset/pull/33137) docs(installation): compare installation methods (@sfirke)
|
||||
- [#33210](https://github.com/apache/superset/pull/33210) docs: Add note on SQL execution security considerations (@sha174n)
|
||||
- [#30047](https://github.com/apache/superset/pull/30047) docs: improve documentation(docs): clarify URL encoding requirement for connection strings (@kalai-logicsoft)
|
||||
- [#33197](https://github.com/apache/superset/pull/33197) chore(deps-dev): bump http-proxy-middleware from 2.0.7 to 2.0.9 in /superset-frontend (@dependabot[bot])
|
||||
- [#33173](https://github.com/apache/superset/pull/33173) docs: add a high-level architecture diagram to the docs (@mistercrunch)
|
||||
- [#33102](https://github.com/apache/superset/pull/33102) chore(deps): bump @babel/runtime from 7.17.2 to 7.27.0 in /superset-frontend/cypress-base (@dependabot[bot])
|
||||
- [#29828](https://github.com/apache/superset/pull/29828) chore(translations): Update PT-BR language (partial) (@felipegranado)
|
||||
- [#33079](https://github.com/apache/superset/pull/33079) chore: Update INTHEWILD.md (@Pedro-Gato)
|
||||
- [#33074](https://github.com/apache/superset/pull/33074) chore: Added Formbricks to INTHEWILD.md (@jobenjada)
|
||||
- [#32941](https://github.com/apache/superset/pull/32941) chore(deps-dev): bump lerna from 8.1.9 to 8.2.1 in /superset-frontend (@dependabot[bot])
|
||||
- [#33045](https://github.com/apache/superset/pull/33045) docs: clarify docker-compose-image-tag instructions (@mistercrunch)
|
||||
- [#33061](https://github.com/apache/superset/pull/33061) chore(helm): bump appVersion to 4.1.2 (@villebro)
|
||||
- [#33028](https://github.com/apache/superset/pull/33028) chore(deps): bump estree-util-value-to-estree from 3.1.1 to 3.3.3 in /docs (@dependabot[bot])
|
||||
- [#33018](https://github.com/apache/superset/pull/33018) docs: add WinWin Network(马上赢) to users list (@Ookong)
|
||||
- [#32890](https://github.com/apache/superset/pull/32890) refactor(IconButton): Refactor IconButton to use Ant Design 5 Card (@Sameerali0)
|
||||
- [#32999](https://github.com/apache/superset/pull/32999) docs: Update documentation about publishing a dashboard (@hverlin)
|
||||
- [#33001](https://github.com/apache/superset/pull/33001) chore(Databricks): Display older Databricks driver as legacy (@Vitor-Avila)
|
||||
- [#32922](https://github.com/apache/superset/pull/32922) chore: bump marshmallow-sqlalchemy to 1.4.0 (@mistercrunch)
|
||||
- [#32952](https://github.com/apache/superset/pull/32952) chore(deps-dev): bump eslint-config-prettier from 10.0.2 to 10.1.1 in /docs (@dependabot[bot])
|
||||
- [#32951](https://github.com/apache/superset/pull/32951) chore(deps): bump antd from 5.24.2 to 5.24.5 in /docs (@dependabot[bot])
|
||||
- [#32950](https://github.com/apache/superset/pull/32950) chore(deps): bump swagger-ui-react from 5.20.0 to 5.20.2 in /docs (@dependabot[bot])
|
||||
- [#32939](https://github.com/apache/superset/pull/32939) chore(deps-dev): bump @babel/compat-data from 7.26.5 to 7.26.8 in /superset-frontend (@dependabot[bot])
|
||||
- [#32937](https://github.com/apache/superset/pull/32937) chore(deps-dev): bump css-minimizer-webpack-plugin from 7.0.0 to 7.0.2 in /superset-frontend (@dependabot[bot])
|
||||
- [#32927](https://github.com/apache/superset/pull/32927) chore(deps): update @types/react-redux requirement from ^7.1.10 to ^7.1.34 in /superset-frontend/plugins/plugin-chart-echarts (@dependabot[bot])
|
||||
- [#32925](https://github.com/apache/superset/pull/32925) chore(deps-dev): bump @typescript-eslint/parser from 8.19.0 to 8.29.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#32924](https://github.com/apache/superset/pull/32924) chore(deps-dev): bump ts-jest from 29.2.5 to 29.3.1 in /superset-websocket (@dependabot[bot])
|
||||
- [#32585](https://github.com/apache/superset/pull/32585) chore(reports): add task for slack channels warm-up (@Usiel)
|
||||
- [#32888](https://github.com/apache/superset/pull/32888) refactor(jinja macro): Update current_user_roles() macro to fetch roles from existing get_user_roles() method (@bmaquet)
|
||||
- [#32901](https://github.com/apache/superset/pull/32901) chore(🦾): bump python grpcio 1.68.0 -> 1.71.0 (@github-actions[bot])
|
||||
- [#32880](https://github.com/apache/superset/pull/32880) refactor(Icons): Add typing support and improve structure (@geido)
|
||||
- [#32860](https://github.com/apache/superset/pull/32860) chore: Removes unused file (@michael-s-molina)
|
||||
- [#32822](https://github.com/apache/superset/pull/32822) docs: added a link to badge releases (@Radovenchyk)
|
||||
- [#32831](https://github.com/apache/superset/pull/32831) chore: updating files for release 4.1.2 (@sadpandajoe)
|
||||
- [#32826](https://github.com/apache/superset/pull/32826) chore(🦾): bump python humanize 4.12.1 -> 4.12.2 (@github-actions[bot])
|
||||
- [#32827](https://github.com/apache/superset/pull/32827) chore(🦾): bump python pyparsing 3.2.1 -> 3.2.2 (@github-actions[bot])
|
||||
- [#32828](https://github.com/apache/superset/pull/32828) chore(🦾): bump python shillelagh subpackage(s) (@github-actions[bot])
|
||||
- [#32825](https://github.com/apache/superset/pull/32825) chore(🦾): bump python click-option-group 0.5.6 -> 0.5.7 (@github-actions[bot])
|
||||
- [#32744](https://github.com/apache/superset/pull/32744) chore(🦾): bump python flask-appbuilder subpackage(s) (@github-actions[bot])
|
||||
- [#32749](https://github.com/apache/superset/pull/32749) chore: replaced the workflow badge link (@Radovenchyk)
|
||||
- [#32742](https://github.com/apache/superset/pull/32742) chore(🦾): bump python slack-sdk 3.34.0 -> 3.35.0 (@github-actions[bot])
|
||||
- [#31255](https://github.com/apache/superset/pull/31255) chore(🦾): bump python shillelagh subpackage(s) (@github-actions[bot])
|
||||
- [#32743](https://github.com/apache/superset/pull/32743) chore(🦾): bump python celery subpackage(s) (@github-actions[bot])
|
||||
- [#32711](https://github.com/apache/superset/pull/32711) chore(lang): update and fix french translations (@CharlesNkdl)
|
||||
- [#31251](https://github.com/apache/superset/pull/31251) chore(🦾): bump python flask-appbuilder subpackage(s) (@github-actions[bot])
|
||||
- [#32112](https://github.com/apache/superset/pull/32112) refactor(Icons): Replaces custom icons with Ant Design 5 icons (@EnxDev)
|
||||
- [#31247](https://github.com/apache/superset/pull/31247) chore(🦾): bump python greenlet (@github-actions[bot])
|
||||
- [#32686](https://github.com/apache/superset/pull/32686) chore(helm): bump postgresql image tag in helm values (@mPyKen)
|
||||
- [#32714](https://github.com/apache/superset/pull/32714) chore(asf): Another `.asf.yaml` touch-up. (@rusackas)
|
||||
- [#32689](https://github.com/apache/superset/pull/32689) chore(docs): touching up AI styling/text (@rusackas)
|
||||
- [#32712](https://github.com/apache/superset/pull/32712) chore(asf): trying to fix `.asf.yaml` again to re-enable Discussions (@rusackas)
|
||||
- [#32710](https://github.com/apache/superset/pull/32710) chore(asf): Removing notifications from `.asf.yaml` - they still don't work :( (@rusackas)
|
||||
- [#32709](https://github.com/apache/superset/pull/32709) chore(asf): fixing(?) `.asf.yaml` (@rusackas)
|
||||
- [#32690](https://github.com/apache/superset/pull/32690) docs(api): correct attribute `name` instead of `table` for GET table_metadata in openapi.json (@hainenber)
|
||||
- [#32688](https://github.com/apache/superset/pull/32688) build(dev-deps): bump prettier to v3.5.3 and follow-up refactor (@hainenber)
|
||||
- [#32697](https://github.com/apache/superset/pull/32697) chore: add Oxylabs to INTHEWILD.md (@rytis-ulys)
|
||||
- [#32407](https://github.com/apache/superset/pull/32407) chore(docs): remove customized "Edit this page on GitHub" button (@hainenber)
|
||||
- [#32580](https://github.com/apache/superset/pull/32580) chore(deps): bump jinja2 from 3.1.5 to 3.1.6 in /superset/translations (@dependabot[bot])
|
||||
- [#32668](https://github.com/apache/superset/pull/32668) docs: add Hometogo to users list (@PedroMartinSteenstrup)
|
||||
- [#32623](https://github.com/apache/superset/pull/32623) chore(examples): Touching up Vehicle Sales a bit (@rusackas)
|
||||
- [#32485](https://github.com/apache/superset/pull/32485) chore: simplify user impersonation (@betodealmeida)
|
||||
- [#32641](https://github.com/apache/superset/pull/32641) chore: add unique option to index migration utils (@villebro)
|
||||
- [#32575](https://github.com/apache/superset/pull/32575) chore(🦾): bump python paramiko 3.5.0 -> 3.5.1 (@github-actions[bot])
|
||||
- [#32639](https://github.com/apache/superset/pull/32639) chore(🦾): bump python croniter 5.0.1 -> 6.0.0 (@github-actions[bot])
|
||||
- [#32637](https://github.com/apache/superset/pull/32637) chore(🦾): bump python flask-session subpackage(s) (@github-actions[bot])
|
||||
- [#32638](https://github.com/apache/superset/pull/32638) chore(🦾): bump python celery subpackage(s) (@github-actions[bot])
|
||||
- [#32636](https://github.com/apache/superset/pull/32636) chore(🦾): bump python importlib-metadata 8.5.0 -> 8.6.1 (@github-actions[bot])
|
||||
- [#32635](https://github.com/apache/superset/pull/32635) chore(🦾): bump python simplejson 3.19.3 -> 3.20.1 (@github-actions[bot])
|
||||
- [#32634](https://github.com/apache/superset/pull/32634) chore(🦾): bump python flask-caching 2.3.0 -> 2.3.1 (@github-actions[bot])
|
||||
- [#32629](https://github.com/apache/superset/pull/32629) chore(🦾): bump python sshtunnel subpackage(s) (@github-actions[bot])
|
||||
- [#32596](https://github.com/apache/superset/pull/32596) chore: fix precommit for eslint (@mistercrunch)
|
||||
- [#32596](https://github.com/apache/superset/pull/32596) chore: fix precommit for eslint (@mistercrunch)
|
||||
- [#32631](https://github.com/apache/superset/pull/32631) chore(🦾): bump python sqlparse 0.5.2 -> 0.5.3 (@github-actions[bot])
|
||||
- [#32628](https://github.com/apache/superset/pull/32628) chore(🦾): bump python greenlet 3.0.3 -> 3.1.1 (@github-actions[bot])
|
||||
- [#32632](https://github.com/apache/superset/pull/32632) chore(🦾): bump python humanize 4.11.0 -> 4.12.1 (@github-actions[bot])
|
||||
- [#32630](https://github.com/apache/superset/pull/32630) chore(🦾): bump python nh3 0.2.19 -> 0.2.21 (@github-actions[bot])
|
||||
- [#32578](https://github.com/apache/superset/pull/32578) chore(🦾): bump python flask-migrate subpackage(s) (@github-actions[bot])
|
||||
- [#32577](https://github.com/apache/superset/pull/32577) chore(🦾): bump python pyparsing 3.2.0 -> 3.2.1 (@github-actions[bot])
|
||||
- [#32581](https://github.com/apache/superset/pull/32581) chore(deps-dev): bump axios from 1.7.7 to 1.8.2 in /superset-embedded-sdk (@dependabot[bot])
|
||||
- [#32582](https://github.com/apache/superset/pull/32582) chore(deps): bump axios from 1.7.8 to 1.8.2 in /docs (@dependabot[bot])
|
||||
- [#32583](https://github.com/apache/superset/pull/32583) chore(deps-dev): bump axios from 1.7.9 to 1.8.2 in /superset-frontend (@dependabot[bot])
|
||||
- [#32603](https://github.com/apache/superset/pull/32603) chore(deps): bump @babel/runtime-corejs3 from 7.26.9 to 7.26.10 in /docs (@dependabot[bot])
|
||||
- [#32598](https://github.com/apache/superset/pull/32598) chore(deps): bump @babel/helpers from 7.24.5 to 7.26.10 in /docs (@dependabot[bot])
|
||||
- [#32604](https://github.com/apache/superset/pull/32604) chore(deps): bump @babel/runtime from 7.26.9 to 7.26.10 in /docs (@dependabot[bot])
|
||||
- [#32607](https://github.com/apache/superset/pull/32607) docs(analytics): actually USING Matomo to track page views/changes (@rusackas)
|
||||
- [#32605](https://github.com/apache/superset/pull/32605) docs: fix typo in ephemeral envs docs (@mistercrunch)
|
||||
- [#32600](https://github.com/apache/superset/pull/32600) docs: add information about ephemeral environments (@mistercrunch)
|
||||
- [#32597](https://github.com/apache/superset/pull/32597) chore: bump postgresql from 15 to 16 (@RealGreenDragon)
|
||||
- [#32602](https://github.com/apache/superset/pull/32602) chore(deps): bump @babel/helpers from 7.17.2 to 7.26.10 in /superset-frontend/cypress-base (@dependabot[bot])
|
||||
- [#32576](https://github.com/apache/superset/pull/32576) chore(🦾): bump python slack-sdk 3.33.4 -> 3.34.0 (@github-actions[bot])
|
||||
- [#32579](https://github.com/apache/superset/pull/32579) chore(🦾): bump python pandas subpackage(s) (@github-actions[bot])
|
||||
- [#32573](https://github.com/apache/superset/pull/32573) chore(🦾): bump python cryptography 43.0.3 -> 44.0.2 (@mistercrunch)
|
||||
- [#32561](https://github.com/apache/superset/pull/32561) chore(docs): Add Flowbird to users list (@EmmanuelCbd)
|
||||
- [#32545](https://github.com/apache/superset/pull/32545) refactor(input): Remove leftover direct usage of Ant Design input (@msyavuz)
|
||||
- [#32550](https://github.com/apache/superset/pull/32550) chore: bump node to v20.18.3 (@villebro)
|
||||
- [#32547](https://github.com/apache/superset/pull/32547) docs: add Canonical to INTHEWILD.md (@personofnorank)
|
||||
- [#32544](https://github.com/apache/superset/pull/32544) chore(Ant Design): Remove unnecessary exports from version 4 (@geido)
|
||||
- [#31770](https://github.com/apache/superset/pull/31770) chore: add logging to index error (@betodealmeida)
|
||||
- [#32529](https://github.com/apache/superset/pull/32529) chore: Caching the Slack channels list (@Vitor-Avila)
|
||||
- [#32527](https://github.com/apache/superset/pull/32527) chore(ci): use npm/yarn lock files where possible (@villebro)
|
||||
- [#32448](https://github.com/apache/superset/pull/32448) chore(deps-dev): bump eslint-config-prettier from 8.10.0 to 10.0.2 in /docs (@dependabot[bot])
|
||||
- [#32437](https://github.com/apache/superset/pull/32437) chore(deps-dev): bump globals from 15.9.0 to 16.0.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#32456](https://github.com/apache/superset/pull/32456) chore(deps): bump markdown-to-jsx from 7.7.3 to 7.7.4 in /superset-frontend (@dependabot[bot])
|
||||
- [#32517](https://github.com/apache/superset/pull/32517) chore(ci): show more failed pre-commit context (@villebro)
|
||||
- [#32470](https://github.com/apache/superset/pull/32470) chore(deps-dev): update @babel/types requirement from ^7.26.3 to ^7.26.9 in /superset-frontend/plugins/plugin-chart-pivot-table (@dependabot[bot])
|
||||
- [#32503](https://github.com/apache/superset/pull/32503) chore(deps-dev): bump @typescript-eslint/eslint-plugin from 8.19.0 to 8.26.0 in /superset-websocket (@dependabot[bot])
|
||||
- [#32501](https://github.com/apache/superset/pull/32501) chore: enable dependabot using uv for auto-bumping python packages (@mistercrunch)
|
||||
- [#30657](https://github.com/apache/superset/pull/30657) chore: various markdown warnings resolved (@CodeWithEmad)
|
||||
- [#32453](https://github.com/apache/superset/pull/32453) chore(deps): bump @deck.gl/react from 9.1.0 to 9.1.4 in /superset-frontend (@dependabot[bot])
|
||||
- [#32460](https://github.com/apache/superset/pull/32460) chore(deps-dev): bump @babel/types from 7.26.7 to 7.26.9 in /superset-frontend (@dependabot[bot])
|
||||
- [#32461](https://github.com/apache/superset/pull/32461) chore(deps): bump @rjsf/utils from 5.24.1 to 5.24.3 in /superset-frontend (@dependabot[bot])
|
||||
- [#32462](https://github.com/apache/superset/pull/32462) chore(deps): bump chrono-node from 2.7.7 to 2.7.8 in /superset-frontend (@dependabot[bot])
|
||||
- [#32440](https://github.com/apache/superset/pull/32440) chore(deps-dev): bump @types/jsonwebtoken from 9.0.6 to 9.0.9 in /superset-websocket (@dependabot[bot])
|
||||
- [#32454](https://github.com/apache/superset/pull/32454) chore(deps): bump swagger-ui-react from 5.19.0 to 5.20.0 in /docs (@dependabot[bot])
|
||||
- [#32476](https://github.com/apache/superset/pull/32476) chore(deps-dev): bump @types/lodash from 4.17.14 to 4.17.16 in /superset-frontend (@dependabot[bot])
|
||||
- [#32447](https://github.com/apache/superset/pull/32447) chore(deps): bump antd from 5.24.1 to 5.24.2 in /docs (@dependabot[bot])
|
||||
- [#32449](https://github.com/apache/superset/pull/32449) chore(deps-dev): bump webpack from 5.97.1 to 5.98.0 in /docs (@dependabot[bot])
|
||||
- [#32452](https://github.com/apache/superset/pull/32452) chore(deps-dev): bump typescript from 5.1.6 to 5.8.2 in /docs (@dependabot[bot])
|
||||
- [#32087](https://github.com/apache/superset/pull/32087) chore(deps-dev): bump @docusaurus/tsconfig from 3.6.3 to 3.7.0 in /docs (@dependabot[bot])
|
||||
- [#32421](https://github.com/apache/superset/pull/32421) docs: add SingleStore to the users list (@tjain-singlestore)
|
||||
- [#32385](https://github.com/apache/superset/pull/32385) docs(config): fill in commonly connection string for Oracle, Presto and SQL Server databases (@hainenber)
|
||||
- [#32322](https://github.com/apache/superset/pull/32322) build(deps): bump major versions for `math-expression-evaluator` and `fetch-mock` + clean up obsolete dev/override packages (@hainenber)
|
||||
- [#32393](https://github.com/apache/superset/pull/32393) chore(docs): fix typos (@omahs)
|
||||
- [#32396](https://github.com/apache/superset/pull/32396) docs: add shipmnts to users list (@ekansh-shipmnts)
|
||||
- [#32380](https://github.com/apache/superset/pull/32380) chore(docs): update instructions for pypi distribution (@sadpandajoe)
|
||||
- [#32379](https://github.com/apache/superset/pull/32379) docs(intro): broaden link to installation options (@sfirke)
|
||||
- [#32334](https://github.com/apache/superset/pull/32334) chore: Upgrade AG Grid to use tree shaking (@kgabryje)
|
||||
- [#32365](https://github.com/apache/superset/pull/32365) chore(cleanup): removing accidentally committed package/lock files. (@rusackas)
|
||||
- [#32313](https://github.com/apache/superset/pull/32313) refactor(DrillDetailTableControls): Upgrade DrillDetailTableControls component to Ant Design 5 (@EnxDev)
|
||||
- [#32363](https://github.com/apache/superset/pull/32363) chore(tests): converting enzyme to RTL, part 3 (@rusackas)
|
||||
- [#32314](https://github.com/apache/superset/pull/32314) refactor(DatabaseSelector): Changes the imported types from antd-4 to antdv-5 (@EnxDev)
|
||||
- [#32349](https://github.com/apache/superset/pull/32349) chore(docs): Fix typo in security.mdx (@amineBouilzmin)
|
||||
- [#32323](https://github.com/apache/superset/pull/32323) ci(type-checking): run type-checking-frontend hook sequentially (@alveifbklsiu259)
|
||||
- [#32341](https://github.com/apache/superset/pull/32341) chore(build): reduce Lodash usage in `superset-frontend` (@hainenber)
|
||||
- [#32302](https://github.com/apache/superset/pull/32302) chore(duckdb): Bump duckdb-engine, duckdb versions (@guenp)
|
||||
- [#32330](https://github.com/apache/superset/pull/32330) chore(deps): bump swagger-ui-react from 5.18.2 to 5.19.0 in /docs (@dependabot[bot])
|
||||
- [#32329](https://github.com/apache/superset/pull/32329) chore(deps): bump antd from 5.22.7 to 5.24.1 in /docs (@dependabot[bot])
|
||||
- [#32327](https://github.com/apache/superset/pull/32327) chore(deps): bump @docsearch/react from 3.8.2 to 3.9.0 in /docs (@dependabot[bot])
|
||||
- [#32319](https://github.com/apache/superset/pull/32319) chore(readme): updating video on Readme page. (@rusackas)
|
||||
- [#32326](https://github.com/apache/superset/pull/32326) chore(docs): Add RIADVICE to companies using Superset (@GhaziTriki)
|
||||
- [#31921](https://github.com/apache/superset/pull/31921) docs: various enhancements across `/docs` workspace (@hainenber)
|
||||
- [#32066](https://github.com/apache/superset/pull/32066) chore(deps): bump core-js from 3.39.0 to 3.40.0 in /superset-frontend/packages/superset-ui-demo (@dependabot[bot])
|
||||
- [#32088](https://github.com/apache/superset/pull/32088) chore(deps-dev): bump @docusaurus/module-type-aliases from 3.6.3 to 3.7.0 in /docs (@dependabot[bot])
|
||||
- [#32316](https://github.com/apache/superset/pull/32316) chore(code owners): adding @mistercrunch to cypress/e2e code owners (@rusackas)
|
||||
- [#32226](https://github.com/apache/superset/pull/32226) chore(tests): Trying to kill enzyme, part 2 (more RTL!) (@rusackas)
|
||||
- [#32090](https://github.com/apache/superset/pull/32090) chore(deps-dev): bump typescript from 5.7.2 to 5.7.3 in /docs (@dependabot[bot])
|
||||
- [#32103](https://github.com/apache/superset/pull/32103) chore(deps-dev): bump @babel/preset-env from 7.26.0 to 7.26.7 in /superset-frontend (@dependabot[bot])
|
||||
- [#32259](https://github.com/apache/superset/pull/32259) chore(be/deps): add comments for un-greppable Python dependencies (@hainenber)
|
||||
- [#32270](https://github.com/apache/superset/pull/32270) chore(deps): bump dompurify from 3.2.3 to 3.2.4 in /superset-frontend (@dependabot[bot])
|
||||
- [#32243](https://github.com/apache/superset/pull/32243) build(fe/dev-deps): remove unused `esbuild` dev deps (@hainenber)
|
||||
- [#32236](https://github.com/apache/superset/pull/32236) chore(deps): bump cryptography from 43.0.3 to 44.0.1 (@dependabot[bot])
|
||||
- [#32142](https://github.com/apache/superset/pull/32142) docs(api): Improve api documentation for dashboard endpoints(filter_state, permalink, embedded) (@msyavuz)
|
||||
- [#32235](https://github.com/apache/superset/pull/32235) chore(backend): replace insecure `shortid` usage for native filter migration with native `uuid` Python implementation (@hainenber)
|
||||
- [#32207](https://github.com/apache/superset/pull/32207) chore: Working toward killing enzyme and cleaning up test noise. (@rusackas)
|
||||
- [#31634](https://github.com/apache/superset/pull/31634) chore(fe): migrate 4 Enzyme-based tests to RTL (@hainenber)
|
||||
- [#32180](https://github.com/apache/superset/pull/32180) docs: Permissions 'can this form get on UserInfoEditView' and 'can this form get on UserInfoEditView' are not associated with Aplha and Gamma by default (@xavier-GitHub76)
|
||||
- [#32192](https://github.com/apache/superset/pull/32192) chore(ci): consolidate Node version reference in CI to associated `.nvmrc` (@hainenber)
|
||||
- [#32010](https://github.com/apache/superset/pull/32010) chore: migrating easy-to-migrate AntD vanilla components (@mistercrunch)
|
||||
- [#32206](https://github.com/apache/superset/pull/32206) docs(docker-compose): remove extra backticks (@jonathanmv)
|
||||
- [#31973](https://github.com/apache/superset/pull/31973) refactor(Popover): Upgrade Popover to Antd5 (@alexandrusoare)
|
||||
- [#31972](https://github.com/apache/superset/pull/31972) refactor(Dropdown): Migrate Dropdown to Ant Design 5 (@msyavuz)
|
||||
- [#32188](https://github.com/apache/superset/pull/32188) docs(typo): PostgresQL corrected to PostgreSQL (@0xasritha)
|
||||
- [#32157](https://github.com/apache/superset/pull/32157) chore: add query context data tests (@eschutho)
|
||||
- [#32085](https://github.com/apache/superset/pull/32085) chore(deps): bump less from 4.2.1 to 4.2.2 in /docs (@dependabot[bot])
|
||||
- [#32171](https://github.com/apache/superset/pull/32171) docs: fix typo in docker compose (@ChrisChinchilla)
|
||||
- [#31999](https://github.com/apache/superset/pull/31999) docs: incorrect psycopg2 package in k8s install instructions (@bensku)
|
||||
@@ -59,7 +59,7 @@ RUN mkdir -p /app/superset/static/assets \
|
||||
# NOTE: we mount packages and plugins as they are referenced in package.json as workspaces
|
||||
# ideally we'd COPY only their package.json. Here npm ci will be cached as long
|
||||
# as the full content of these folders don't change, yielding a decent cache reuse rate.
|
||||
# Note that it's not possible to selectively COPY or mount using blobs.
|
||||
# Note that's it's not possible selectively COPY of mount using blobs.
|
||||
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=cache,target=/root/.cache \
|
||||
@@ -74,7 +74,7 @@ RUN --mount=type=bind,source=./superset-frontend/package.json,target=./package.j
|
||||
COPY superset-frontend /app/superset-frontend
|
||||
|
||||
######################################################################
|
||||
# superset-node is used for compiling frontend assets
|
||||
# superset-node used for compile frontend assets
|
||||
######################################################################
|
||||
FROM superset-node-ci AS superset-node
|
||||
|
||||
@@ -90,7 +90,7 @@ RUN --mount=type=cache,target=/root/.npm \
|
||||
# Copy translation files
|
||||
COPY superset/translations /app/superset/translations
|
||||
|
||||
# Build translations if enabled, then cleanup localization files
|
||||
# Build the frontend if not in dev mode
|
||||
RUN if [ "$BUILD_TRANSLATIONS" = "true" ]; then \
|
||||
npm run build-translation; \
|
||||
fi; \
|
||||
|
||||
@@ -32,10 +32,11 @@ else
|
||||
SUPERSET_VERSION="${1}"
|
||||
SUPERSET_RC="${2}"
|
||||
SUPERSET_PGP_FULLNAME="${3}"
|
||||
SUPERSET_VERSION_RC="${SUPERSET_VERSION}rc${SUPERSET_RC}"
|
||||
SUPERSET_RELEASE_RC_TARBALL="apache_superset-${SUPERSET_VERSION_RC}-source.tar.gz"
|
||||
fi
|
||||
|
||||
SUPERSET_VERSION_RC="${SUPERSET_VERSION}rc${SUPERSET_RC}"
|
||||
|
||||
if [ -z "${SUPERSET_SVN_DEV_PATH}" ]; then
|
||||
SUPERSET_SVN_DEV_PATH="$HOME/svn/superset_dev"
|
||||
fi
|
||||
|
||||
@@ -28,7 +28,6 @@ These features are considered **unfinished** and should only be used on developm
|
||||
[//]: # "PLEASE KEEP THE LIST SORTED ALPHABETICALLY"
|
||||
|
||||
- ALERT_REPORT_TABS
|
||||
- DATE_RANGE_TIMESHIFTS_ENABLED
|
||||
- ENABLE_ADVANCED_DATA_TYPES
|
||||
- PRESTO_EXPAND_DATA
|
||||
- SHARE_QUERIES_VIA_KV_STORE
|
||||
|
||||
@@ -94,9 +94,9 @@ under the License.
|
||||
| can available domains on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|
||||
| can request access on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|
||||
| can dashboard on Superset |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O|
|
||||
| can post on TableSchemaView |:heavy_check_mark:|O|O|:heavy_check_mark:|
|
||||
| can expanded on TableSchemaView |:heavy_check_mark:|O|O|:heavy_check_mark:|
|
||||
| can delete on TableSchemaView |:heavy_check_mark:|O|O|:heavy_check_mark:|
|
||||
| can post on TableSchemaView |:heavy_check_mark:|:heavy_check_mark:|O|O|
|
||||
| can expanded on TableSchemaView |:heavy_check_mark:|:heavy_check_mark:|O|O|
|
||||
| can delete on TableSchemaView |:heavy_check_mark:|:heavy_check_mark:|O|O|
|
||||
| can get on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
|
||||
| can post on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
|
||||
| can delete query on TabStateView |:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|
|
||||
|
||||
10
UPDATING.md
10
UPDATING.md
@@ -22,14 +22,7 @@ under the License.
|
||||
This file documents any backwards-incompatible changes in Superset and
|
||||
assists people when migrating to a new version.
|
||||
|
||||
## 6.0.0
|
||||
- [34536](https://github.com/apache/superset/pull/34536): The `ENVIRONMENT_TAG_CONFIG` color values have changed to support only Ant Design semantic colors. Update your `superset_config.py`:
|
||||
- Change `"error.base"` to just `"error"` after this PR
|
||||
- Change any hex color values to one of: `"success"`, `"processing"`, `"error"`, `"warning"`, `"default"`
|
||||
- Custom colors are no longer supported to maintain consistency with Ant Design components
|
||||
- [34561](https://github.com/apache/superset/pull/34561) Added tiled screenshot functionality for Playwright-based reports to handle large dashboards more efficiently. When enabled (default: `SCREENSHOT_TILED_ENABLED = True`), dashboards with 20+ charts or height exceeding 5000px will be captured using multiple viewport-sized tiles and combined into a single image. This improves report generation performance and reliability for large dashboards.
|
||||
Note: Pillow is now a required dependency (previously optional) to support image processing for tiled screenshots.
|
||||
`thumbnails` optional dependency is now deprecated and will be removed in the next major release (7.0).
|
||||
## Next
|
||||
- [33084](https://github.com/apache/superset/pull/33084) The DISALLOWED_SQL_FUNCTIONS configuration now includes additional potentially sensitive database functions across PostgreSQL, MySQL, SQLite, MS SQL Server, and ClickHouse. Existing queries using these functions may now be blocked. Review your SQL Lab queries and dashboards if you encounter "disallowed function" errors after upgrading
|
||||
- [34235](https://github.com/apache/superset/pull/34235) CSV exports now use `utf-8-sig` encoding by default to include a UTF-8 BOM, improving compatibility with Excel.
|
||||
- [34258](https://github.com/apache/superset/pull/34258) changing the default in Dockerfile to INCLUDE_CHROMIUM="false" (from "true") in the past. This ensures the `lean` layer is lean by default, and people can opt-in to the `chromium` layer by setting the build arg `INCLUDE_CHROMIUM=true`. This is a breaking change for anyone using the `lean` layer, as it will no longer include Chromium by default.
|
||||
@@ -39,7 +32,6 @@ Note: Pillow is now a required dependency (previously optional) to support image
|
||||
- [32317](https://github.com/apache/superset/pull/32317) The horizontal filter bar feature is now out of testing/beta development and its feature flag `HORIZONTAL_FILTER_BAR` has been removed.
|
||||
- [31590](https://github.com/apache/superset/pull/31590) Marks the begining of intricate work around supporting dynamic Theming, and breaks support for [THEME_OVERRIDES](https://github.com/apache/superset/blob/732de4ac7fae88e29b7f123b6cbb2d7cd411b0e4/superset/config.py#L671) in favor of a new theming system based on AntD V5. Likely this will be in disrepair until settling over the 5.x lifecycle.
|
||||
- [32432](https://github.com/apache/superset/pull/31260) Moves the List Roles FAB view to the frontend and requires `FAB_ADD_SECURITY_API` to be enabled in the configuration and `superset init` to be executed.
|
||||
- [34319](https://github.com/apache/superset/pull/34319) Drill to Detail and Drill By is now supported in Embedded mode, and also with the `DASHBOARD_RBAC` FF. If you don't want to expose these features in Embedded / `DASHBOARD_RBAC`, make sure the roles used for Embedded / `DASHBOARD_RBAC`don't have the required permissions to perform D2D actions.
|
||||
|
||||
## 5.0.0
|
||||
|
||||
|
||||
@@ -17,47 +17,16 @@
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Lightweight docker-compose for running multiple Superset instances
|
||||
# This includes only essential services: database and Superset app (no Redis)
|
||||
# This includes only essential services: database, Redis, and Superset app
|
||||
#
|
||||
# RUNNING SUPERSET:
|
||||
# 1. Start services: docker-compose -f docker-compose-light.yml up
|
||||
# 2. Access at: http://localhost:9001 (or NODE_PORT if specified)
|
||||
#
|
||||
# RUNNING MULTIPLE INSTANCES:
|
||||
# IMPORTANT: To run multiple instances in parallel:
|
||||
# - Use different project names: docker-compose -p project1 -f docker-compose-light.yml up
|
||||
# - Use different NODE_PORT values: NODE_PORT=9002 docker-compose -p project2 -f docker-compose-light.yml up
|
||||
# - Volumes are isolated by project name (e.g., project1_db_home_light, project2_db_home_light)
|
||||
# - Database name is intentionally different (superset_light) to prevent accidental cross-connections
|
||||
#
|
||||
# RUNNING TESTS WITH PYTEST:
|
||||
# Tests run in an isolated environment with a separate test database.
|
||||
# The pytest-runner service automatically creates and initializes the test database on first use.
|
||||
#
|
||||
# Basic usage:
|
||||
# docker-compose -f docker-compose-light.yml run --rm pytest-runner pytest tests/unit_tests/
|
||||
#
|
||||
# Run specific test file:
|
||||
# docker-compose -f docker-compose-light.yml run --rm pytest-runner pytest tests/unit_tests/test_foo.py
|
||||
#
|
||||
# Run with pytest options:
|
||||
# docker-compose -f docker-compose-light.yml run --rm pytest-runner pytest -v -s -x tests/
|
||||
#
|
||||
# Force reload test database and run tests (when tests are failing due to bad state):
|
||||
# docker-compose -f docker-compose-light.yml run --rm -e FORCE_RELOAD=true pytest-runner pytest tests/
|
||||
#
|
||||
# Run any command in test environment:
|
||||
# docker-compose -f docker-compose-light.yml run --rm pytest-runner bash
|
||||
# docker-compose -f docker-compose-light.yml run --rm pytest-runner pytest --collect-only
|
||||
#
|
||||
# For parallel test execution with different projects:
|
||||
# docker-compose -p project1 -f docker-compose-light.yml run --rm pytest-runner pytest tests/
|
||||
#
|
||||
# DEVELOPMENT TIPS:
|
||||
# - First test run takes ~20-30 seconds (database creation + initialization)
|
||||
# - Subsequent runs are fast (~2-3 seconds startup)
|
||||
# - Use FORCE_RELOAD=true when you need a clean test database
|
||||
# - Tests use SimpleCache instead of Redis (no Redis required)
|
||||
# - Set SUPERSET_LOG_LEVEL=debug in docker/.env-local for detailed logs
|
||||
# For verbose logging during development:
|
||||
# - Set SUPERSET_LOG_LEVEL=debug in docker/.env-local for detailed Superset logs
|
||||
# -----------------------------------------------------------------------
|
||||
x-superset-user: &superset-user root
|
||||
x-superset-volumes: &superset-volumes
|
||||
@@ -87,14 +56,13 @@ services:
|
||||
required: false
|
||||
image: postgres:16
|
||||
restart: unless-stopped
|
||||
# No host port mapping - only accessible within Docker network
|
||||
volumes:
|
||||
- db_home_light:/var/lib/postgresql/data
|
||||
- ./docker/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
||||
environment:
|
||||
# Override database name to avoid conflicts
|
||||
POSTGRES_DB: superset_light
|
||||
# Increase max connections for test runs
|
||||
command: postgres -c max_connections=200
|
||||
|
||||
superset-light:
|
||||
env_file:
|
||||
@@ -182,34 +150,6 @@ services:
|
||||
required: false
|
||||
volumes: *superset-volumes
|
||||
|
||||
pytest-runner:
|
||||
build:
|
||||
<<: *common-build
|
||||
entrypoint: ["/app/docker/docker-pytest-entrypoint.sh"]
|
||||
env_file:
|
||||
- path: docker/.env # default
|
||||
required: true
|
||||
- path: docker/.env-local # optional override
|
||||
required: false
|
||||
profiles:
|
||||
- test # Only starts when --profile test is used
|
||||
depends_on:
|
||||
db-light:
|
||||
condition: service_started
|
||||
user: *superset-user
|
||||
volumes: *superset-volumes
|
||||
environment:
|
||||
# Test-specific database configuration
|
||||
DATABASE_HOST: db-light
|
||||
DATABASE_DB: test
|
||||
POSTGRES_DB: test
|
||||
# Point to test database
|
||||
SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@db-light:5432/test
|
||||
# Use the light test config that doesn't require Redis
|
||||
SUPERSET_CONFIG: superset_test_config_light
|
||||
# Python path includes test directory
|
||||
PYTHONPATH: /app/pythonpath:/app/docker/pythonpath_dev:/app
|
||||
|
||||
volumes:
|
||||
superset_home_light:
|
||||
external: false
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
#!/bin/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
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
echo "Waiting for database to be ready..."
|
||||
for i in {1..30}; do
|
||||
if python3 -c "
|
||||
import psycopg2
|
||||
try:
|
||||
conn = psycopg2.connect(host='db-light', user='superset', password='superset', database='superset_light')
|
||||
conn.close()
|
||||
print('Database is ready!')
|
||||
except:
|
||||
exit(1)
|
||||
" 2>/dev/null; then
|
||||
echo "Database connection established!"
|
||||
break
|
||||
fi
|
||||
echo "Waiting for database... ($i/30)"
|
||||
if [ $i -eq 30 ]; then
|
||||
echo "Database connection timeout after 30 seconds"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Handle database setup based on FORCE_RELOAD
|
||||
if [ "${FORCE_RELOAD}" = "true" ]; then
|
||||
echo "Force reload requested - resetting test database"
|
||||
# Drop and recreate the test database using Python
|
||||
python3 -c "
|
||||
import psycopg2
|
||||
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
|
||||
|
||||
# Connect to default database
|
||||
conn = psycopg2.connect(host='db-light', user='superset', password='superset', database='superset_light')
|
||||
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
|
||||
cur = conn.cursor()
|
||||
|
||||
# Drop and recreate test database
|
||||
try:
|
||||
cur.execute('DROP DATABASE IF EXISTS test')
|
||||
except:
|
||||
pass
|
||||
|
||||
cur.execute('CREATE DATABASE test')
|
||||
conn.close()
|
||||
|
||||
# Connect to test database to create schemas
|
||||
conn = psycopg2.connect(host='db-light', user='superset', password='superset', database='test')
|
||||
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute('CREATE SCHEMA sqllab_test_db')
|
||||
cur.execute('CREATE SCHEMA admin_database')
|
||||
|
||||
cur.close()
|
||||
conn.close()
|
||||
print('Test database reset successfully')
|
||||
"
|
||||
# Use --no-reset-db since we already reset it
|
||||
FLAGS="--no-reset-db"
|
||||
else
|
||||
echo "Using existing test database (set FORCE_RELOAD=true to reset)"
|
||||
FLAGS="--no-reset-db"
|
||||
|
||||
# Ensure test database exists using Python
|
||||
python3 -c "
|
||||
import psycopg2
|
||||
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
|
||||
|
||||
# Check if test database exists
|
||||
try:
|
||||
conn = psycopg2.connect(host='db-light', user='superset', password='superset', database='test')
|
||||
conn.close()
|
||||
print('Test database already exists')
|
||||
except:
|
||||
print('Creating test database...')
|
||||
# Connect to default database to create test database
|
||||
conn = psycopg2.connect(host='db-light', user='superset', password='superset', database='superset_light')
|
||||
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
|
||||
cur = conn.cursor()
|
||||
|
||||
# Create test database
|
||||
cur.execute('CREATE DATABASE test')
|
||||
conn.close()
|
||||
|
||||
# Connect to test database to create schemas
|
||||
conn = psycopg2.connect(host='db-light', user='superset', password='superset', database='test')
|
||||
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute('CREATE SCHEMA IF NOT EXISTS sqllab_test_db')
|
||||
cur.execute('CREATE SCHEMA IF NOT EXISTS admin_database')
|
||||
|
||||
cur.close()
|
||||
conn.close()
|
||||
print('Test database created successfully')
|
||||
"
|
||||
fi
|
||||
|
||||
# Always run database migrations to ensure schema is up to date
|
||||
echo "Running database migrations..."
|
||||
cd /app
|
||||
superset db upgrade
|
||||
|
||||
# Initialize test environment if needed
|
||||
if [ "${FORCE_RELOAD}" = "true" ] || [ ! -f "/app/superset_home/.test_initialized" ]; then
|
||||
echo "Initializing test environment..."
|
||||
# Run initialization commands
|
||||
superset init
|
||||
echo "Loading test users..."
|
||||
superset load-test-users
|
||||
|
||||
# Mark as initialized
|
||||
touch /app/superset_home/.test_initialized
|
||||
else
|
||||
echo "Test environment already initialized (skipping init and load-test-users)"
|
||||
echo "Tip: Use FORCE_RELOAD=true to reinitialize the test database"
|
||||
fi
|
||||
|
||||
# Create missing scripts needed for tests
|
||||
if [ ! -f "/app/scripts/tag_latest_release.sh" ]; then
|
||||
echo "Creating missing tag_latest_release.sh script for tests..."
|
||||
cp /app/docker/tag_latest_release.sh /app/scripts/tag_latest_release.sh 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Install pip module for Shillelagh compatibility (aligns with CI environment)
|
||||
echo "Installing pip module for Shillelagh compatibility..."
|
||||
uv pip install pip
|
||||
|
||||
# If arguments provided, execute them
|
||||
if [ $# -gt 0 ]; then
|
||||
exec "$@"
|
||||
fi
|
||||
@@ -23,57 +23,25 @@ MIN_MEM_FREE_GB=3
|
||||
MIN_MEM_FREE_KB=$(($MIN_MEM_FREE_GB*1000000))
|
||||
|
||||
echo_mem_warn() {
|
||||
# Check if running in Codespaces first
|
||||
if [[ -n "${CODESPACES}" ]]; then
|
||||
echo "Memory available: Codespaces managed"
|
||||
return
|
||||
fi
|
||||
MEM_FREE_KB=$(awk '/MemFree/ { printf "%s \n", $2 }' /proc/meminfo)
|
||||
MEM_FREE_GB=$(awk '/MemFree/ { printf "%s \n", $2/1024/1024 }' /proc/meminfo)
|
||||
|
||||
# Check platform and get memory accordingly
|
||||
if [[ -f /proc/meminfo ]]; then
|
||||
# Linux
|
||||
if grep -q MemAvailable /proc/meminfo; then
|
||||
MEM_AVAIL_KB=$(awk '/MemAvailable/ { printf "%s \n", $2 }' /proc/meminfo)
|
||||
MEM_AVAIL_GB=$(awk '/MemAvailable/ { printf "%s \n", $2/1024/1024 }' /proc/meminfo)
|
||||
else
|
||||
MEM_AVAIL_KB=$(awk '/MemFree/ { printf "%s \n", $2 }' /proc/meminfo)
|
||||
MEM_AVAIL_GB=$(awk '/MemFree/ { printf "%s \n", $2/1024/1024 }' /proc/meminfo)
|
||||
fi
|
||||
elif [[ "$(uname)" == "Darwin" ]]; then
|
||||
# macOS - use vm_stat to get free memory
|
||||
# vm_stat reports in pages, typically 4096 bytes per page
|
||||
PAGE_SIZE=$(pagesize)
|
||||
FREE_PAGES=$(vm_stat | awk '/Pages free:/ {print $3}' | tr -d '.')
|
||||
INACTIVE_PAGES=$(vm_stat | awk '/Pages inactive:/ {print $3}' | tr -d '.')
|
||||
# Free + inactive pages give us available memory (similar to MemAvailable on Linux)
|
||||
AVAIL_PAGES=$((FREE_PAGES + INACTIVE_PAGES))
|
||||
MEM_AVAIL_KB=$((AVAIL_PAGES * PAGE_SIZE / 1024))
|
||||
MEM_AVAIL_GB=$(echo "scale=2; $MEM_AVAIL_KB / 1024 / 1024" | bc)
|
||||
else
|
||||
# Other platforms
|
||||
echo "Memory available: Unable to determine"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "${MEM_AVAIL_KB}" -lt "${MIN_MEM_FREE_KB}" ]]; then
|
||||
if [[ "${MEM_FREE_KB}" -lt "${MIN_MEM_FREE_KB}" ]]; then
|
||||
cat <<EOF
|
||||
===============================================
|
||||
======== Memory Insufficient Warning =========
|
||||
===============================================
|
||||
|
||||
It looks like you only have ${MEM_AVAIL_GB}GB of
|
||||
memory ${MEM_TYPE}. Please increase your Docker
|
||||
It looks like you only have ${MEM_FREE_GB}GB of
|
||||
memory free. Please increase your Docker
|
||||
resources to at least ${MIN_MEM_FREE_GB}GB
|
||||
|
||||
Note: During builds, available memory may be
|
||||
temporarily low due to caching and compilation.
|
||||
|
||||
===============================================
|
||||
======== Memory Insufficient Warning =========
|
||||
===============================================
|
||||
EOF
|
||||
else
|
||||
echo "Memory available: ${MEM_AVAIL_GB} GB"
|
||||
echo "Memory check Ok [${MEM_FREE_GB}GB free]"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# 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.
|
||||
#
|
||||
# Test configuration for docker-compose-light.yml - uses SimpleCache instead of Redis
|
||||
|
||||
# Import all settings from the main test config first
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Add the tests directory to the path to import the test config
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
from tests.integration_tests.superset_test_config import * # noqa: F403
|
||||
|
||||
# Override Redis-based caching to use simple in-memory cache
|
||||
CACHE_CONFIG = {
|
||||
"CACHE_TYPE": "SimpleCache",
|
||||
"CACHE_DEFAULT_TIMEOUT": 300,
|
||||
"CACHE_KEY_PREFIX": "superset_test_",
|
||||
}
|
||||
|
||||
DATA_CACHE_CONFIG = {
|
||||
**CACHE_CONFIG,
|
||||
"CACHE_DEFAULT_TIMEOUT": 30,
|
||||
"CACHE_KEY_PREFIX": "superset_test_data_",
|
||||
}
|
||||
|
||||
# Keep SimpleCache for these as they're already using it
|
||||
# FILTER_STATE_CACHE_CONFIG - already SimpleCache in parent
|
||||
# EXPLORE_FORM_DATA_CACHE_CONFIG - already SimpleCache in parent
|
||||
|
||||
# Disable Celery for lightweight testing
|
||||
CELERY_CONFIG = None
|
||||
|
||||
# Use FileSystemCache for SQL Lab results instead of Redis
|
||||
from flask_caching.backends.filesystemcache import FileSystemCache # noqa: E402
|
||||
|
||||
RESULTS_BACKEND = FileSystemCache("/app/superset_home/sqllab_test")
|
||||
|
||||
# Override WEBDRIVER_BASEURL for tests to match expected values
|
||||
WEBDRIVER_BASEURL = "http://0.0.0.0:8080/"
|
||||
WEBDRIVER_BASEURL_USER_FRIENDLY = WEBDRIVER_BASEURL
|
||||
@@ -1,190 +0,0 @@
|
||||
#! /bin/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.
|
||||
|
||||
run_git_tag () {
|
||||
if [[ "$DRY_RUN" == "false" ]] && [[ "$SKIP_TAG" == "false" ]]
|
||||
then
|
||||
git tag -a -f latest "${GITHUB_TAG_NAME}" -m "latest tag"
|
||||
echo "${GITHUB_TAG_NAME} has been tagged 'latest'"
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
###
|
||||
# separating out git commands into functions so they can be mocked in unit tests
|
||||
###
|
||||
git_show_ref () {
|
||||
if [[ "$TEST_ENV" == "true" ]]
|
||||
then
|
||||
if [[ "$GITHUB_TAG_NAME" == "does_not_exist" ]]
|
||||
# mock return for testing only
|
||||
then
|
||||
echo ""
|
||||
else
|
||||
echo "2817aebd69dc7d199ec45d973a2079f35e5658b6 refs/tags/${GITHUB_TAG_NAME}"
|
||||
fi
|
||||
fi
|
||||
result=$(git show-ref "${GITHUB_TAG_NAME}")
|
||||
echo "${result}"
|
||||
}
|
||||
|
||||
get_latest_tag_list () {
|
||||
if [[ "$TEST_ENV" == "true" ]]
|
||||
then
|
||||
echo "(tag: 2.1.0, apache/2.1test)"
|
||||
else
|
||||
result=$(git show-ref --tags --dereference latest | awk '{print $2}' | xargs git show --pretty=tformat:%d -s | grep tag:)
|
||||
echo "${result}"
|
||||
fi
|
||||
}
|
||||
###
|
||||
|
||||
split_string () {
|
||||
local version="$1"
|
||||
local delimiter="$2"
|
||||
local components=()
|
||||
local tmp=""
|
||||
for (( i=0; i<${#version}; i++ )); do
|
||||
local char="${version:$i:1}"
|
||||
if [[ "$char" != "$delimiter" ]]; then
|
||||
tmp="$tmp$char"
|
||||
elif [[ -n "$tmp" ]]; then
|
||||
components+=("$tmp")
|
||||
tmp=""
|
||||
fi
|
||||
done
|
||||
if [[ -n "$tmp" ]]; then
|
||||
components+=("$tmp")
|
||||
fi
|
||||
echo "${components[@]}"
|
||||
}
|
||||
|
||||
DRY_RUN=false
|
||||
|
||||
# get params passed in with script when it was run
|
||||
# --dry-run is optional and returns the value of SKIP_TAG, but does not run the git tag statement
|
||||
# A tag name is required as a param. A SHA won't work. You must first tag a sha with a release number
|
||||
# and then run this script
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
|
||||
case $key in
|
||||
--dry-run)
|
||||
DRY_RUN=true
|
||||
shift # past value
|
||||
;;
|
||||
*) # this should be the tag name
|
||||
GITHUB_TAG_NAME=$key
|
||||
shift # past value
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "${GITHUB_TAG_NAME}" ]; then
|
||||
echo "Missing tag parameter, usage: ./scripts/tag_latest_release.sh <GITHUB_TAG_NAME>"
|
||||
echo "SKIP_TAG=true" >> $GITHUB_OUTPUT
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$(git_show_ref)" ]; then
|
||||
echo "The tag ${GITHUB_TAG_NAME} does not exist. Please use a different tag."
|
||||
echo "SKIP_TAG=true" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# check that this tag only contains a proper semantic version
|
||||
if ! [[ ${GITHUB_TAG_NAME} =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]
|
||||
then
|
||||
echo "This tag ${GITHUB_TAG_NAME} is not a valid release version. Not tagging."
|
||||
echo "SKIP_TAG=true" >> $GITHUB_OUTPUT
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## split the current GITHUB_TAG_NAME into an array at the dot
|
||||
THIS_TAG_NAME=$(split_string "${GITHUB_TAG_NAME}" ".")
|
||||
|
||||
# look up the 'latest' tag on git
|
||||
LATEST_TAG_LIST=$(get_latest_tag_list) || echo 'not found'
|
||||
|
||||
# if 'latest' tag doesn't exist, then set this commit to latest
|
||||
if [[ -z "$LATEST_TAG_LIST" ]]
|
||||
then
|
||||
echo "there are no latest tags yet, so I'm going to start by tagging this sha as the latest"
|
||||
run_git_tag
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# remove parenthesis and tag: from the list of tags
|
||||
LATEST_TAGS_STRINGS=$(echo "$LATEST_TAG_LIST" | sed 's/tag: \([^,]*\)/\1/g' | tr -d '()')
|
||||
|
||||
LATEST_TAGS=$(split_string "$LATEST_TAGS_STRINGS" ",")
|
||||
TAGS=($(split_string "$LATEST_TAGS" " "))
|
||||
|
||||
# Initialize a flag for comparison result
|
||||
compare_result=""
|
||||
|
||||
# Iterate through the tags of the latest release
|
||||
for tag in $TAGS
|
||||
do
|
||||
if [[ $tag == "latest" ]]; then
|
||||
continue
|
||||
else
|
||||
## extract just the version from this tag
|
||||
LATEST_RELEASE_TAG="$tag"
|
||||
echo "LATEST_RELEASE_TAG: ${LATEST_RELEASE_TAG}"
|
||||
|
||||
# check that this only contains a proper semantic version
|
||||
if ! [[ ${LATEST_RELEASE_TAG} =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]
|
||||
then
|
||||
echo "'Latest' has been associated with tag ${LATEST_RELEASE_TAG} which is not a valid release version. Looking for another."
|
||||
continue
|
||||
fi
|
||||
echo "The current release with the latest tag is version ${LATEST_RELEASE_TAG}"
|
||||
# Split the version strings into arrays
|
||||
THIS_TAG_NAME_ARRAY=($(split_string "$THIS_TAG_NAME" "."))
|
||||
LATEST_RELEASE_TAG_ARRAY=($(split_string "$LATEST_RELEASE_TAG" "."))
|
||||
|
||||
# Iterate through the components of the version strings
|
||||
for (( j=0; j<${#THIS_TAG_NAME_ARRAY[@]}; j++ )); do
|
||||
echo "Comparing ${THIS_TAG_NAME_ARRAY[$j]} to ${LATEST_RELEASE_TAG_ARRAY[$j]}"
|
||||
if [[ $((THIS_TAG_NAME_ARRAY[$j])) > $((LATEST_RELEASE_TAG_ARRAY[$j])) ]]; then
|
||||
compare_result="greater"
|
||||
break
|
||||
elif [[ $((THIS_TAG_NAME_ARRAY[$j])) < $((LATEST_RELEASE_TAG_ARRAY[$j])) ]]; then
|
||||
compare_result="lesser"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
# Determine the result based on the comparison
|
||||
if [[ -z "$compare_result" ]]; then
|
||||
echo "Versions are equal"
|
||||
echo "SKIP_TAG=true" >> $GITHUB_OUTPUT
|
||||
elif [[ "$compare_result" == "greater" ]]; then
|
||||
echo "This release tag ${GITHUB_TAG_NAME} is newer than the latest."
|
||||
echo "SKIP_TAG=false" >> $GITHUB_OUTPUT
|
||||
# Add other actions you want to perform for a newer version
|
||||
elif [[ "$compare_result" == "lesser" ]]; then
|
||||
echo "This release tag ${GITHUB_TAG_NAME} is older than the latest."
|
||||
echo "This release tag ${GITHUB_TAG_NAME} is not the latest. Not tagging."
|
||||
# if you've gotten this far, then we don't want to run any tags in the next step
|
||||
echo "SKIP_TAG=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
@@ -13,9 +13,9 @@ apache-superset>=6.0
|
||||
Superset now rides on **Ant Design v5's token-based theming**.
|
||||
Every Antd token works, plus a handful of Superset-specific ones for charts and dashboard chrome.
|
||||
|
||||
## Managing Themes via UI
|
||||
## Managing Themes via CRUD Interface
|
||||
|
||||
Superset includes a built-in **Theme Management** interface accessible from the admin menu under **Settings > Themes**.
|
||||
Superset now includes a built-in **Theme Management** interface accessible from the admin menu under **Settings > Themes**.
|
||||
|
||||
### Creating a New Theme
|
||||
|
||||
@@ -29,38 +29,22 @@ Superset includes a built-in **Theme Management** interface accessible from the
|
||||
|
||||
You can also extend with Superset-specific tokens (documented in the default theme object) before you import.
|
||||
|
||||
### System Theme Administration
|
||||
|
||||
When `ENABLE_UI_THEME_ADMINISTRATION = True` is configured, administrators can manage system-wide themes directly from the UI:
|
||||
|
||||
#### Setting System Themes
|
||||
- **System Default Theme**: Click the sun icon on any theme to set it as the system-wide default
|
||||
- **System Dark Theme**: Click the moon icon on any theme to set it as the system dark mode theme
|
||||
- **Automatic OS Detection**: When both default and dark themes are set, Superset automatically detects and applies the appropriate theme based on OS preferences
|
||||
|
||||
#### Managing System Themes
|
||||
- System themes are indicated with special badges in the theme list
|
||||
- Only administrators with write permissions can modify system theme settings
|
||||
- Removing a system theme designation reverts to configuration file defaults
|
||||
|
||||
### Applying Themes to Dashboards
|
||||
|
||||
Once created, themes can be applied to individual dashboards:
|
||||
- Edit any dashboard and select your custom theme from the theme dropdown
|
||||
- Each dashboard can have its own theme, allowing for branded or context-specific styling
|
||||
|
||||
## Configuration Options
|
||||
## Alternative: Instance-wide Configuration
|
||||
|
||||
### Python Configuration
|
||||
For system-wide theming, you can configure default themes via Python configuration:
|
||||
|
||||
Configure theme behavior via `superset_config.py`:
|
||||
### Setting Default Themes
|
||||
|
||||
```python
|
||||
# Enable UI-based theme administration for admins
|
||||
ENABLE_UI_THEME_ADMINISTRATION = True
|
||||
# superset_config.py
|
||||
|
||||
# Optional: Set initial default themes via configuration
|
||||
# These can be overridden via the UI when ENABLE_UI_THEME_ADMINISTRATION = True
|
||||
# Default theme (light mode)
|
||||
THEME_DEFAULT = {
|
||||
"token": {
|
||||
"colorPrimary": "#2893B3",
|
||||
@@ -69,7 +53,7 @@ THEME_DEFAULT = {
|
||||
}
|
||||
}
|
||||
|
||||
# Optional: Dark theme configuration
|
||||
# Dark theme configuration
|
||||
THEME_DARK = {
|
||||
"algorithm": "dark",
|
||||
"token": {
|
||||
@@ -78,28 +62,23 @@ THEME_DARK = {
|
||||
}
|
||||
}
|
||||
|
||||
# To force a single theme on all users, set THEME_DARK = None
|
||||
# When both themes are defined (via UI or config):
|
||||
# - Users can manually switch between themes
|
||||
# - OS preference detection is automatically enabled
|
||||
# Theme behavior settings
|
||||
THEME_SETTINGS = {
|
||||
"enforced": False, # If True, forces default theme always
|
||||
"allowSwitching": True, # Allow users to switch between themes
|
||||
"allowOSPreference": True, # Auto-detect system theme preference
|
||||
}
|
||||
```
|
||||
|
||||
### Migration from Configuration to UI
|
||||
### Copying Themes from CRUD Interface
|
||||
|
||||
When `ENABLE_UI_THEME_ADMINISTRATION = True`:
|
||||
To use a theme created via the CRUD interface as your system default:
|
||||
|
||||
1. System themes set via the UI take precedence over configuration file settings
|
||||
2. The UI shows which themes are currently set as system defaults
|
||||
3. Administrators can change system themes without restarting Superset
|
||||
4. Configuration file themes serve as fallbacks when no UI themes are set
|
||||
1. Navigate to **Settings > Themes** and edit your desired theme
|
||||
2. Copy the complete JSON configuration from the theme definition field
|
||||
3. Paste it directly into your `superset_config.py` as shown above
|
||||
|
||||
### Copying Themes Between Systems
|
||||
|
||||
To export a theme for use in configuration files or another instance:
|
||||
|
||||
1. Navigate to **Settings > Themes** and click the export icon on your desired theme
|
||||
2. Extract the JSON configuration from the exported YAML file
|
||||
3. Use this JSON in your `superset_config.py` or import it into another Superset instance
|
||||
Restart Superset to apply changes.
|
||||
|
||||
## Theme Development Workflow
|
||||
|
||||
@@ -108,85 +87,8 @@ To export a theme for use in configuration files or another instance:
|
||||
3. **Apply**: Assign themes to specific dashboards or configure instance-wide
|
||||
4. **Iterate**: Modify theme JSON directly in the CRUD interface or re-import from the theme editor
|
||||
|
||||
## Custom Fonts
|
||||
|
||||
Superset supports custom fonts through runtime configuration, allowing you to use branded or custom typefaces without rebuilding the application.
|
||||
|
||||
### Configuring Custom Fonts
|
||||
|
||||
Add font URLs to your `superset_config.py`:
|
||||
|
||||
```python
|
||||
# Load fonts from Google Fonts, Adobe Fonts, or self-hosted sources
|
||||
CUSTOM_FONT_URLS = [
|
||||
"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap",
|
||||
"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap",
|
||||
]
|
||||
|
||||
# Update CSP to allow font sources
|
||||
TALISMAN_CONFIG = {
|
||||
"content_security_policy": {
|
||||
"font-src": ["'self'", "https://fonts.googleapis.com", "https://fonts.gstatic.com"],
|
||||
"style-src": ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using Custom Fonts in Themes
|
||||
|
||||
Once configured, reference the fonts in your theme configuration:
|
||||
|
||||
```python
|
||||
THEME_DEFAULT = {
|
||||
"token": {
|
||||
"fontFamily": "Inter, -apple-system, BlinkMacSystemFont, sans-serif",
|
||||
"fontFamilyCode": "JetBrains Mono, Monaco, monospace",
|
||||
# ... other theme tokens
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or in the CRUD interface theme JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"token": {
|
||||
"fontFamily": "Inter, -apple-system, BlinkMacSystemFont, sans-serif",
|
||||
"fontFamilyCode": "JetBrains Mono, Monaco, monospace"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Font Sources
|
||||
|
||||
- **Google Fonts**: Free, CDN-hosted fonts with wide variety
|
||||
- **Adobe Fonts**: Premium fonts (requires subscription and kit ID)
|
||||
- **Self-hosted**: Place font files in `/static/assets/fonts/` and reference via CSS
|
||||
|
||||
This feature works with the stock Docker image - no custom build required!
|
||||
|
||||
## Advanced Features
|
||||
|
||||
- **System Themes**: Manage system-wide default and dark themes via UI or configuration
|
||||
- **System Themes**: Superset includes built-in light and dark themes
|
||||
- **Per-Dashboard Theming**: Each dashboard can have its own visual identity
|
||||
- **JSON Editor**: Edit theme configurations directly within Superset's interface
|
||||
- **Custom Fonts**: Load external fonts via configuration without rebuilding
|
||||
- **OS Dark Mode Detection**: Automatically switches themes based on system preferences
|
||||
- **Theme Import/Export**: Share themes between instances via YAML files
|
||||
|
||||
## API Access
|
||||
|
||||
For programmatic theme management, Superset provides REST endpoints:
|
||||
|
||||
- `GET /api/v1/theme/` - List all themes
|
||||
- `POST /api/v1/theme/` - Create a new theme
|
||||
- `PUT /api/v1/theme/{id}` - Update a theme
|
||||
- `DELETE /api/v1/theme/{id}` - Delete a theme
|
||||
- `PUT /api/v1/theme/{id}/set_system_default` - Set as system default theme (admin only)
|
||||
- `PUT /api/v1/theme/{id}/set_system_dark` - Set as system dark theme (admin only)
|
||||
- `DELETE /api/v1/theme/unset_system_default` - Remove system default designation
|
||||
- `DELETE /api/v1/theme/unset_system_dark` - Remove system dark designation
|
||||
- `GET /api/v1/theme/export/` - Export themes as YAML
|
||||
- `POST /api/v1/theme/import/` - Import themes from YAML
|
||||
|
||||
These endpoints require appropriate permissions and are subject to RBAC controls.
|
||||
|
||||
@@ -120,78 +120,6 @@ docker volume rm superset_db_home
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
## GitHub Codespaces (Cloud Development)
|
||||
|
||||
GitHub Codespaces provides a complete, pre-configured development environment in the cloud. This is ideal for:
|
||||
- Quick contributions without local setup
|
||||
- Consistent development environments across team members
|
||||
- Working from devices that can't run Docker locally
|
||||
- Safe experimentation in isolated environments
|
||||
|
||||
:::info
|
||||
We're grateful to GitHub for providing this excellent cloud development service that makes
|
||||
contributing to Apache Superset more accessible to developers worldwide.
|
||||
:::
|
||||
|
||||
### Getting Started with Codespaces
|
||||
|
||||
1. **Create a Codespace**: Use this pre-configured link that sets up everything you need:
|
||||
|
||||
[**Launch Superset Codespace →**](https://github.com/codespaces/new?skip_quickstart=true&machine=standardLinux32gb&repo=39464018&ref=master&devcontainer_path=.devcontainer%2Fdevcontainer.json&geo=UsWest)
|
||||
|
||||
:::caution
|
||||
**Important**: You must select at least the **4 CPU / 16GB RAM** machine type (pre-selected in the link above).
|
||||
Smaller instances will not have sufficient resources to run Superset effectively.
|
||||
:::
|
||||
|
||||
2. **Wait for Setup**: The initial setup takes several minutes. The Codespace will:
|
||||
- Build the development container
|
||||
- Install all dependencies
|
||||
- Start all required services (PostgreSQL, Redis, etc.)
|
||||
- Initialize the database with example data
|
||||
|
||||
3. **Access Superset**: Once ready, check the **PORTS** tab in VS Code for port `9001`.
|
||||
Click the globe icon to open Superset in your browser.
|
||||
- Default credentials: `admin` / `admin`
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Auto-reload**: Both Python and TypeScript files auto-refresh on save
|
||||
- **Pre-installed Extensions**: VS Code extensions for Python, TypeScript, and database tools
|
||||
- **Multiple Instances**: Run multiple Codespaces for different branches/features
|
||||
- **SSH Access**: Connect via terminal using `gh cs ssh` or through the GitHub web UI
|
||||
- **VS Code Integration**: Works seamlessly with VS Code desktop app
|
||||
|
||||
### Managing Codespaces
|
||||
|
||||
- **List active Codespaces**: `gh cs list`
|
||||
- **SSH into a Codespace**: `gh cs ssh`
|
||||
- **Stop a Codespace**: Via GitHub UI or `gh cs stop`
|
||||
- **Delete a Codespace**: Via GitHub UI or `gh cs delete`
|
||||
|
||||
### Debugging and Logs
|
||||
|
||||
Since Codespaces uses `docker-compose-light.yml`, you can monitor all services:
|
||||
|
||||
```bash
|
||||
# Stream logs from all services
|
||||
docker compose -f docker-compose-light.yml logs -f
|
||||
|
||||
# Stream logs from a specific service
|
||||
docker compose -f docker-compose-light.yml logs -f superset
|
||||
|
||||
# View last 100 lines and follow
|
||||
docker compose -f docker-compose-light.yml logs --tail=100 -f
|
||||
|
||||
# List all running services
|
||||
docker compose -f docker-compose-light.yml ps
|
||||
```
|
||||
|
||||
:::tip
|
||||
Codespaces automatically stop after 30 minutes of inactivity to save resources.
|
||||
Your work is preserved and you can restart anytime.
|
||||
:::
|
||||
|
||||
## Installing Development Tools
|
||||
|
||||
:::note
|
||||
@@ -421,6 +349,14 @@ Then make sure you run your WSGI server using the right worker type:
|
||||
gunicorn "superset.app:create_app()" -k "geventwebsocket.gunicorn.workers.GeventWebSocketWorker" -b 127.0.0.1:8088 --reload
|
||||
```
|
||||
|
||||
You can log anything to the browser console, including objects:
|
||||
|
||||
```python
|
||||
from superset import app
|
||||
app.logger.error('An exception occurred!')
|
||||
app.logger.info(form_data)
|
||||
```
|
||||
|
||||
### Frontend
|
||||
|
||||
Frontend assets (TypeScript, JavaScript, CSS, and images) must be compiled in order to properly display the web UI. The `superset-frontend` directory contains all NPM-managed frontend assets. Note that for some legacy pages there are additional frontend assets bundled with Flask-Appbuilder (e.g. jQuery and bootstrap). These are not managed by NPM and may be phased out in the future.
|
||||
|
||||
@@ -2,20 +2,6 @@
|
||||
title: CVEs fixed by release
|
||||
sidebar_position: 2
|
||||
---
|
||||
#### Version 5.0.0
|
||||
|
||||
| CVE | Title | Affected |
|
||||
|:---------------|:-----------------------------------------------------------------------------------|---------:|
|
||||
| CVE-2025-55673 | Exposure of Sensitive Information to an Unauthorized Actor | < 5.0.0 |
|
||||
| CVE-2025-55674 | Improper Neutralization of Special Elements used in an SQL Command | < 5.0.0 |
|
||||
| CVE-2025-55675 | Improper Access Control leading to Information Disclosure | < 5.0.0 |
|
||||
|
||||
#### Version 4.1.3
|
||||
|
||||
| CVE | Title | Affected |
|
||||
|:---------------|:-----------------------------------------------------------------------------------|---------:|
|
||||
| CVE-2025-55672 | Improper Neutralization of Input During Web Page Generation | < 4.1.3 |
|
||||
|
||||
#### Version 4.1.2
|
||||
|
||||
| CVE | Title | Affected |
|
||||
|
||||
@@ -28,9 +28,6 @@ const globals = require('globals');
|
||||
const { defineConfig, globalIgnores } = require('eslint/config');
|
||||
|
||||
module.exports = defineConfig([
|
||||
{
|
||||
files: ['**/*.{js,jsx,ts,tsx}'],
|
||||
},
|
||||
globalIgnores(['build/**/*', '.docusaurus/**/*', 'node_modules/**/*']),
|
||||
js.configs.recommended,
|
||||
...ts.configs.recommended,
|
||||
@@ -39,7 +36,7 @@ module.exports = defineConfig([
|
||||
files: ['eslint.config.js'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-require-imports': 'off',
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
@@ -71,5 +68,5 @@ module.exports = defineConfig([
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
])
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids",
|
||||
"typecheck": "tsc",
|
||||
"eslint": "eslint ."
|
||||
"eslint": "eslint . --ext .js,.jsx,.ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.0.0",
|
||||
@@ -26,33 +26,33 @@
|
||||
"@emotion/styled": "^10.0.27",
|
||||
"@saucelabs/theme-github-codeblock": "^0.3.0",
|
||||
"@superset-ui/style": "^0.14.23",
|
||||
"antd": "^5.26.7",
|
||||
"antd": "^5.26.3",
|
||||
"docusaurus-plugin-less": "^2.0.2",
|
||||
"less": "^4.4.0",
|
||||
"less": "^4.3.0",
|
||||
"less-loader": "^12.3.0",
|
||||
"prism-react-renderer": "^2.4.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-github-btn": "^1.4.0",
|
||||
"react-svg-pan-zoom": "^3.13.1",
|
||||
"swagger-ui-react": "^5.27.1"
|
||||
"swagger-ui-react": "^5.26.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "^3.8.1",
|
||||
"@docusaurus/tsconfig": "^3.8.1",
|
||||
"@eslint/js": "^9.32.0",
|
||||
"@eslint/js": "^9.31.0",
|
||||
"@types/react": "^19.1.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.37.0",
|
||||
"@typescript-eslint/parser": "^8.37.0",
|
||||
"eslint": "^9.32.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-prettier": "^5.5.3",
|
||||
"eslint": "^9.31.0",
|
||||
"eslint-config-prettier": "^10.1.5",
|
||||
"eslint-plugin-prettier": "^5.5.1",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"globals": "^16.3.0",
|
||||
"prettier": "^3.6.2",
|
||||
"typescript": "~5.8.3",
|
||||
"typescript-eslint": "^8.39.0",
|
||||
"webpack": "^5.101.0"
|
||||
"typescript-eslint": "^8.37.0",
|
||||
"webpack": "^5.99.9"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
||||
327
docs/yarn.lock
327
docs/yarn.lock
@@ -2150,7 +2150,14 @@
|
||||
resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz"
|
||||
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
|
||||
|
||||
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0":
|
||||
"@eslint-community/eslint-utils@^4.2.0":
|
||||
version "4.4.1"
|
||||
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz"
|
||||
integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^3.4.3"
|
||||
|
||||
"@eslint-community/eslint-utils@^4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz#607084630c6c033992a082de6e6fbc1a8b52175a"
|
||||
integrity sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==
|
||||
@@ -2198,20 +2205,20 @@
|
||||
minimatch "^3.1.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@eslint/js@9.32.0", "@eslint/js@^9.32.0":
|
||||
version "9.32.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.32.0.tgz#a02916f58bd587ea276876cb051b579a3d75d091"
|
||||
integrity sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==
|
||||
"@eslint/js@9.31.0", "@eslint/js@^9.31.0":
|
||||
version "9.31.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.31.0.tgz#adb1f39953d8c475c4384b67b67541b0d7206ed8"
|
||||
integrity sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==
|
||||
|
||||
"@eslint/object-schema@^2.1.6":
|
||||
version "2.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f"
|
||||
integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==
|
||||
|
||||
"@eslint/plugin-kit@^0.3.4":
|
||||
version "0.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz#c6b9f165e94bf4d9fdd493f1c028a94aaf5fc1cc"
|
||||
integrity sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==
|
||||
"@eslint/plugin-kit@^0.3.1":
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz#32926b59bd407d58d817941e48b2a7049359b1fd"
|
||||
integrity sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==
|
||||
dependencies:
|
||||
"@eslint/core" "^0.15.1"
|
||||
levn "^0.4.1"
|
||||
@@ -2505,10 +2512,10 @@
|
||||
classnames "^2.3.2"
|
||||
rc-util "^5.24.4"
|
||||
|
||||
"@rc-component/trigger@^2.0.0", "@rc-component/trigger@^2.1.1", "@rc-component/trigger@^2.3.0":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@rc-component/trigger/-/trigger-2.3.0.tgz#9499ada078daca9dd99d01f0f0743ee1ab9e398b"
|
||||
integrity sha512-iwaxZyzOuK0D7lS+0AQEtW52zUWxoGqTGkke3dRyb8pYiShmRpCjB/8TzPI4R6YySCH7Vm9BZj/31VPiiQTLBg==
|
||||
"@rc-component/trigger@^2.0.0", "@rc-component/trigger@^2.1.1", "@rc-component/trigger@^2.2.7":
|
||||
version "2.2.7"
|
||||
resolved "https://registry.yarnpkg.com/@rc-component/trigger/-/trigger-2.2.7.tgz#a2b97ecbb93280a3c424e51fa415b371b355d76a"
|
||||
integrity sha512-Qggj4Z0AA2i5dJhzlfFSmg1Qrziu8dsdHOihROL5Kl18seO2Eh/ZaTYt2c8a/CyGaTChnFry7BEYew1+/fhSbA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.2"
|
||||
"@rc-component/portal" "^1.1.0"
|
||||
@@ -3415,10 +3422,10 @@
|
||||
dependencies:
|
||||
"@types/estree" "*"
|
||||
|
||||
"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6", "@types/estree@^1.0.8":
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
|
||||
integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
|
||||
"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6":
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8"
|
||||
integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==
|
||||
|
||||
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0":
|
||||
version "5.0.6"
|
||||
@@ -3717,79 +3724,79 @@
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@8.39.0", "@typescript-eslint/eslint-plugin@^8.37.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz#c9afec1866ee1a6ea3d768b5f8e92201efbbba06"
|
||||
integrity sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==
|
||||
"@typescript-eslint/eslint-plugin@8.37.0", "@typescript-eslint/eslint-plugin@^8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.37.0.tgz#332392883f936137cd6252c8eb236d298e514e70"
|
||||
integrity sha512-jsuVWeIkb6ggzB+wPCsR4e6loj+rM72ohW6IBn2C+5NCvfUVY8s33iFPySSVXqtm5Hu29Ne/9bnA0JmyLmgenA==
|
||||
dependencies:
|
||||
"@eslint-community/regexpp" "^4.10.0"
|
||||
"@typescript-eslint/scope-manager" "8.39.0"
|
||||
"@typescript-eslint/type-utils" "8.39.0"
|
||||
"@typescript-eslint/utils" "8.39.0"
|
||||
"@typescript-eslint/visitor-keys" "8.39.0"
|
||||
"@typescript-eslint/scope-manager" "8.37.0"
|
||||
"@typescript-eslint/type-utils" "8.37.0"
|
||||
"@typescript-eslint/utils" "8.37.0"
|
||||
"@typescript-eslint/visitor-keys" "8.37.0"
|
||||
graphemer "^1.4.0"
|
||||
ignore "^7.0.0"
|
||||
natural-compare "^1.4.0"
|
||||
ts-api-utils "^2.1.0"
|
||||
|
||||
"@typescript-eslint/parser@8.39.0", "@typescript-eslint/parser@^8.37.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.39.0.tgz#c4b895d7a47f4cd5ee6ee77ea30e61d58b802008"
|
||||
integrity sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==
|
||||
"@typescript-eslint/parser@8.37.0", "@typescript-eslint/parser@^8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.37.0.tgz#b87f6b61e25ad5cc5bbf8baf809b8da889c89804"
|
||||
integrity sha512-kVIaQE9vrN9RLCQMQ3iyRlVJpTiDUY6woHGb30JDkfJErqrQEmtdWH3gV0PBAfGZgQXoqzXOO0T3K6ioApbbAA==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "8.39.0"
|
||||
"@typescript-eslint/types" "8.39.0"
|
||||
"@typescript-eslint/typescript-estree" "8.39.0"
|
||||
"@typescript-eslint/visitor-keys" "8.39.0"
|
||||
"@typescript-eslint/scope-manager" "8.37.0"
|
||||
"@typescript-eslint/types" "8.37.0"
|
||||
"@typescript-eslint/typescript-estree" "8.37.0"
|
||||
"@typescript-eslint/visitor-keys" "8.37.0"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/project-service@8.39.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.39.0.tgz#71cb29c3f8139f99a905b8705127bffc2ae84759"
|
||||
integrity sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==
|
||||
"@typescript-eslint/project-service@8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.37.0.tgz#0594352e32a4ac9258591b88af77b5653800cdfe"
|
||||
integrity sha512-BIUXYsbkl5A1aJDdYJCBAo8rCEbAvdquQ8AnLb6z5Lp1u3x5PNgSSx9A/zqYc++Xnr/0DVpls8iQ2cJs/izTXA==
|
||||
dependencies:
|
||||
"@typescript-eslint/tsconfig-utils" "^8.39.0"
|
||||
"@typescript-eslint/types" "^8.39.0"
|
||||
"@typescript-eslint/tsconfig-utils" "^8.37.0"
|
||||
"@typescript-eslint/types" "^8.37.0"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@8.39.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz#ba4bf6d8257bbc172c298febf16bc22df4856570"
|
||||
integrity sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==
|
||||
"@typescript-eslint/scope-manager@8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.37.0.tgz#a31a3c80ca2ef4ed58de13742debb692e7d4c0a4"
|
||||
integrity sha512-0vGq0yiU1gbjKob2q691ybTg9JX6ShiVXAAfm2jGf3q0hdP6/BruaFjL/ManAR/lj05AvYCH+5bbVo0VtzmjOA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.39.0"
|
||||
"@typescript-eslint/visitor-keys" "8.39.0"
|
||||
"@typescript-eslint/types" "8.37.0"
|
||||
"@typescript-eslint/visitor-keys" "8.37.0"
|
||||
|
||||
"@typescript-eslint/tsconfig-utils@8.39.0", "@typescript-eslint/tsconfig-utils@^8.39.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz#b2e87fef41a3067c570533b722f6af47be213f13"
|
||||
integrity sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==
|
||||
"@typescript-eslint/tsconfig-utils@8.37.0", "@typescript-eslint/tsconfig-utils@^8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.37.0.tgz#47a2760d265c6125f8e7864bc5c8537cad2bd053"
|
||||
integrity sha512-1/YHvAVTimMM9mmlPvTec9NP4bobA1RkDbMydxG8omqwJJLEW/Iy2C4adsAESIXU3WGLXFHSZUU+C9EoFWl4Zg==
|
||||
|
||||
"@typescript-eslint/type-utils@8.39.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz#310ec781ae5e7bb0f5940bfd652573587f22786b"
|
||||
integrity sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==
|
||||
"@typescript-eslint/type-utils@8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.37.0.tgz#2a682e4c6ff5886712dad57e9787b5e417124507"
|
||||
integrity sha512-SPkXWIkVZxhgwSwVq9rqj/4VFo7MnWwVaRNznfQDc/xPYHjXnPfLWn+4L6FF1cAz6e7dsqBeMawgl7QjUMj4Ow==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.39.0"
|
||||
"@typescript-eslint/typescript-estree" "8.39.0"
|
||||
"@typescript-eslint/utils" "8.39.0"
|
||||
"@typescript-eslint/types" "8.37.0"
|
||||
"@typescript-eslint/typescript-estree" "8.37.0"
|
||||
"@typescript-eslint/utils" "8.37.0"
|
||||
debug "^4.3.4"
|
||||
ts-api-utils "^2.1.0"
|
||||
|
||||
"@typescript-eslint/types@8.39.0", "@typescript-eslint/types@^8.39.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.39.0.tgz#80f010b7169d434a91cd0529d70a528dbc9c99c6"
|
||||
integrity sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==
|
||||
"@typescript-eslint/types@8.37.0", "@typescript-eslint/types@^8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.37.0.tgz#09517aa9625eb3c68941dde3ac8835740587b6ff"
|
||||
integrity sha512-ax0nv7PUF9NOVPs+lmQ7yIE7IQmAf8LGcXbMvHX5Gm+YJUYNAl340XkGnrimxZ0elXyoQJuN5sbg6C4evKA4SQ==
|
||||
|
||||
"@typescript-eslint/typescript-estree@8.39.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz#b9477a5c47a0feceffe91adf553ad9a3cd4cb3d6"
|
||||
integrity sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==
|
||||
"@typescript-eslint/typescript-estree@8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.37.0.tgz#a07e4574d8e6e4355a558f61323730c987f5fcbc"
|
||||
integrity sha512-zuWDMDuzMRbQOM+bHyU4/slw27bAUEcKSKKs3hcv2aNnc/tvE/h7w60dwVw8vnal2Pub6RT1T7BI8tFZ1fE+yg==
|
||||
dependencies:
|
||||
"@typescript-eslint/project-service" "8.39.0"
|
||||
"@typescript-eslint/tsconfig-utils" "8.39.0"
|
||||
"@typescript-eslint/types" "8.39.0"
|
||||
"@typescript-eslint/visitor-keys" "8.39.0"
|
||||
"@typescript-eslint/project-service" "8.37.0"
|
||||
"@typescript-eslint/tsconfig-utils" "8.37.0"
|
||||
"@typescript-eslint/types" "8.37.0"
|
||||
"@typescript-eslint/visitor-keys" "8.37.0"
|
||||
debug "^4.3.4"
|
||||
fast-glob "^3.3.2"
|
||||
is-glob "^4.0.3"
|
||||
@@ -3797,22 +3804,22 @@
|
||||
semver "^7.6.0"
|
||||
ts-api-utils "^2.1.0"
|
||||
|
||||
"@typescript-eslint/utils@8.39.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.39.0.tgz#dfea42f3c7ec85f9f3e994ff0bba8f3b2f09e220"
|
||||
integrity sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==
|
||||
"@typescript-eslint/utils@8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.37.0.tgz#189ea59b2709f5d898614611f091a776751ee335"
|
||||
integrity sha512-TSFvkIW6gGjN2p6zbXo20FzCABbyUAuq6tBvNRGsKdsSQ6a7rnV6ADfZ7f4iI3lIiXc4F4WWvtUfDw9CJ9pO5A==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.7.0"
|
||||
"@typescript-eslint/scope-manager" "8.39.0"
|
||||
"@typescript-eslint/types" "8.39.0"
|
||||
"@typescript-eslint/typescript-estree" "8.39.0"
|
||||
"@typescript-eslint/scope-manager" "8.37.0"
|
||||
"@typescript-eslint/types" "8.37.0"
|
||||
"@typescript-eslint/typescript-estree" "8.37.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@8.39.0":
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz#5d619a6e810cdd3fd1913632719cbccab08bf875"
|
||||
integrity sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==
|
||||
"@typescript-eslint/visitor-keys@8.37.0":
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.37.0.tgz#cdb6a6bd3e8d6dd69bd70c1bdda36e2d18737455"
|
||||
integrity sha512-YzfhzcTnZVPiLfP/oeKtDp2evwvHLMe0LOy7oe+hb9KKIumLNohYS9Hgp1ifwpu42YWxhZE8yieggz6JpqO/1w==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.39.0"
|
||||
"@typescript-eslint/types" "8.37.0"
|
||||
eslint-visitor-keys "^4.2.1"
|
||||
|
||||
"@ungap/structured-clone@^1.0.0":
|
||||
@@ -3959,11 +3966,6 @@ accepts@~1.3.4, accepts@~1.3.8:
|
||||
mime-types "~2.1.34"
|
||||
negotiator "0.6.3"
|
||||
|
||||
acorn-import-phases@^1.0.3:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7"
|
||||
integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==
|
||||
|
||||
acorn-jsx@^5.0.0, acorn-jsx@^5.3.2:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
@@ -3976,7 +3978,12 @@ acorn-walk@^8.0.0:
|
||||
dependencies:
|
||||
acorn "^8.11.0"
|
||||
|
||||
acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.15.0, acorn@^8.8.2:
|
||||
acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.8.2:
|
||||
version "8.14.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb"
|
||||
integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
|
||||
|
||||
acorn@^8.15.0:
|
||||
version "8.15.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
|
||||
integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
|
||||
@@ -4100,10 +4107,10 @@ ansi-styles@^6.1.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
|
||||
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
|
||||
|
||||
antd@^5.26.7:
|
||||
version "5.26.7"
|
||||
resolved "https://registry.yarnpkg.com/antd/-/antd-5.26.7.tgz#e2f7e37330b27eec0de7a7789767975373f61602"
|
||||
integrity sha512-iCyXN6+i2CUVEOSzzJKfbKeg115qoJhGvSkCh5uzAf9hANwHUOJQhsMn+KtN+Lx/2NQ6wfM7nGZ+7NPNO5Pn1w==
|
||||
antd@^5.26.3:
|
||||
version "5.26.3"
|
||||
resolved "https://registry.yarnpkg.com/antd/-/antd-5.26.3.tgz#cbbb7e1b48a972dc7b6ee8b6948f51cc91c263f8"
|
||||
integrity sha512-M/s9Q39h/+G7AWnS6fbNxmAI9waTH4ti022GVEXBLq2j810V1wJ3UOQps13nEilzDNcyxnFN/EIbqIgS7wSYaA==
|
||||
dependencies:
|
||||
"@ant-design/colors" "^7.2.1"
|
||||
"@ant-design/cssinjs" "^1.23.0"
|
||||
@@ -4116,7 +4123,7 @@ antd@^5.26.7:
|
||||
"@rc-component/mutate-observer" "^1.1.0"
|
||||
"@rc-component/qrcode" "~1.0.0"
|
||||
"@rc-component/tour" "~1.15.1"
|
||||
"@rc-component/trigger" "^2.3.0"
|
||||
"@rc-component/trigger" "^2.2.7"
|
||||
classnames "^2.5.1"
|
||||
copy-to-clipboard "^3.3.3"
|
||||
dayjs "^1.11.11"
|
||||
@@ -4146,7 +4153,7 @@ antd@^5.26.7:
|
||||
rc-switch "~4.1.0"
|
||||
rc-table "~7.51.1"
|
||||
rc-tabs "~15.6.1"
|
||||
rc-textarea "~1.10.1"
|
||||
rc-textarea "~1.10.0"
|
||||
rc-tooltip "~6.4.0"
|
||||
rc-tree "~5.13.1"
|
||||
rc-tree-select "~5.27.0"
|
||||
@@ -4501,7 +4508,17 @@ braces@^3.0.3, braces@~3.0.2:
|
||||
dependencies:
|
||||
fill-range "^7.1.1"
|
||||
|
||||
browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.25.0:
|
||||
browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4:
|
||||
version "4.24.4"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b"
|
||||
integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30001688"
|
||||
electron-to-chromium "^1.5.73"
|
||||
node-releases "^2.0.19"
|
||||
update-browserslist-db "^1.1.1"
|
||||
|
||||
browserslist@^4.25.0:
|
||||
version "4.25.0"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.0.tgz#986aa9c6d87916885da2b50d8eb577ac8d133b2c"
|
||||
integrity sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==
|
||||
@@ -4603,7 +4620,7 @@ caniuse-api@^3.0.0:
|
||||
lodash.memoize "^4.1.2"
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702:
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001688, caniuse-lite@^1.0.30001702:
|
||||
version "1.0.30001714"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001714.tgz#cfd27ff07e6fa20a0f45c7a10d28a0ffeaba2122"
|
||||
integrity sha512-mtgapdwDLSSBnCI3JokHM7oEQBLxiJKVRtg10AxM1AyeiKcM96f0Mkbqeq+1AbiCtvMcHRulAAEMu693JrSWqg==
|
||||
@@ -5605,13 +5622,20 @@ debug@2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0:
|
||||
debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
|
||||
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
debug@^4.3.2, debug@^4.3.4:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
|
||||
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
decode-named-character-reference@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz#5d6ce68792808901210dac42a8e9853511e2b8bf"
|
||||
@@ -5879,6 +5903,11 @@ electron-to-chromium@^1.5.160:
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.170.tgz#9f6697de4339e24da8b234e4492a9ecb91f5989c"
|
||||
integrity sha512-GP+M7aeluQo9uAyiTCxgIj/j+PrWhMlY7LFVj8prlsPljd0Fdg9AprlfUi+OCSFWy9Y5/2D/Jrj9HS8Z4rpKWA==
|
||||
|
||||
electron-to-chromium@^1.5.73:
|
||||
version "1.5.138"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.138.tgz#319e775179bd0889ed96a04d4390d355fb315a44"
|
||||
integrity sha512-FWlQc52z1dXqm+9cCJ2uyFgJkESd+16j6dBEjsgDNuHjBpuIzL8/lRc0uvh1k8RNI6waGo6tcy2DvwkTBJOLDg==
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
@@ -5923,10 +5952,10 @@ encodeurl@~2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58"
|
||||
integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==
|
||||
|
||||
enhanced-resolve@^5.17.2:
|
||||
version "5.18.2"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz#7903c5b32ffd4b2143eeb4b92472bd68effd5464"
|
||||
integrity sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==
|
||||
enhanced-resolve@^5.17.1:
|
||||
version "5.18.1"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf"
|
||||
integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.4"
|
||||
tapable "^2.2.0"
|
||||
@@ -6132,15 +6161,15 @@ escape-string-regexp@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8"
|
||||
integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
|
||||
|
||||
eslint-config-prettier@^10.1.8:
|
||||
version "10.1.8"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz#15734ce4af8c2778cc32f0b01b37b0b5cd1ecb97"
|
||||
integrity sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==
|
||||
eslint-config-prettier@^10.1.5:
|
||||
version "10.1.5"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz#00c18d7225043b6fbce6a665697377998d453782"
|
||||
integrity sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==
|
||||
|
||||
eslint-plugin-prettier@^5.5.3:
|
||||
version "5.5.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.3.tgz#1f88e9220a72ac8be171eec5f9d4e4d529b5f4a0"
|
||||
integrity sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==
|
||||
eslint-plugin-prettier@^5.5.1:
|
||||
version "5.5.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.1.tgz#470820964de9aedb37e9ce62c3266d2d26d08d15"
|
||||
integrity sha512-dobTkHT6XaEVOo8IO90Q4DOSxnm3Y151QxPJlM/vKC0bVy+d6cVWQZLlFiuZPP0wS6vZwSKeJgKkcS+KfMBlRw==
|
||||
dependencies:
|
||||
prettier-linter-helpers "^1.0.0"
|
||||
synckit "^0.11.7"
|
||||
@@ -6195,10 +6224,10 @@ eslint-visitor-keys@^4.2.1:
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1"
|
||||
integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==
|
||||
|
||||
eslint@^9.32.0:
|
||||
version "9.32.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.32.0.tgz#4ea28df4a8dbc454e1251e0f3aed4bcf4ce50a47"
|
||||
integrity sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==
|
||||
eslint@^9.31.0:
|
||||
version "9.31.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.31.0.tgz#9a488e6da75bbe05785cd62e43c5ea99356d21ba"
|
||||
integrity sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.2.0"
|
||||
"@eslint-community/regexpp" "^4.12.1"
|
||||
@@ -6206,8 +6235,8 @@ eslint@^9.32.0:
|
||||
"@eslint/config-helpers" "^0.3.0"
|
||||
"@eslint/core" "^0.15.0"
|
||||
"@eslint/eslintrc" "^3.3.1"
|
||||
"@eslint/js" "9.32.0"
|
||||
"@eslint/plugin-kit" "^0.3.4"
|
||||
"@eslint/js" "9.31.0"
|
||||
"@eslint/plugin-kit" "^0.3.1"
|
||||
"@humanfs/node" "^0.16.6"
|
||||
"@humanwhocodes/module-importer" "^1.0.1"
|
||||
"@humanwhocodes/retry" "^0.4.2"
|
||||
@@ -8034,10 +8063,10 @@ less-loader@^12.3.0:
|
||||
resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-12.3.0.tgz#d4a00361568be86a97da3df4f16954b0d4c15340"
|
||||
integrity sha512-0M6+uYulvYIWs52y0LqN4+QM9TqWAohYSNTo4htE8Z7Cn3G/qQMEmktfHmyJT23k+20kU9zHH2wrfFXkxNLtVw==
|
||||
|
||||
less@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/less/-/less-4.4.0.tgz#deaf881f4880ee80691beae925b8fac699d3a76d"
|
||||
integrity sha512-kdTwsyRuncDfjEs0DlRILWNvxhDG/Zij4YLO4TMJgDLW+8OzpfkdPnRgrsRuY1o+oaxJGWsps5f/RVBgGmmN0w==
|
||||
less@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/less/-/less-4.3.0.tgz#ef0cfc260a9ca8079ed8d0e3512bda8a12c82f2a"
|
||||
integrity sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==
|
||||
dependencies:
|
||||
copy-anything "^2.0.1"
|
||||
parse-node-version "^1.0.1"
|
||||
@@ -9040,6 +9069,11 @@ ms@2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
ms@2.1.3, ms@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
@@ -10680,10 +10714,10 @@ rc-tabs@~15.6.1:
|
||||
rc-resize-observer "^1.0.0"
|
||||
rc-util "^5.34.1"
|
||||
|
||||
rc-textarea@~1.10.0, rc-textarea@~1.10.1:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-textarea/-/rc-textarea-1.10.2.tgz#459e3574a95c32939c6793045a1e4db04cb514cc"
|
||||
integrity sha512-HfaeXiaSlpiSp0I/pvWpecFEHpVysZ9tpDLNkxQbMvMz6gsr7aVZ7FpWP9kt4t7DB+jJXesYS0us1uPZnlRnwQ==
|
||||
rc-textarea@~1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-textarea/-/rc-textarea-1.10.0.tgz#f8f962ef83be0b8e35db97cf03dbfb86ddd9c46c"
|
||||
integrity sha512-ai9IkanNuyBS4x6sOL8qu/Ld40e6cEs6pgk93R+XLYg0mDSjNBGey6/ZpDs5+gNLD7urQ14po3V6Ck2dJLt9SA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.1"
|
||||
@@ -12066,10 +12100,10 @@ swagger-client@^3.35.5:
|
||||
ramda "^0.30.1"
|
||||
ramda-adjunct "^5.1.0"
|
||||
|
||||
swagger-ui-react@^5.27.1:
|
||||
version "5.27.1"
|
||||
resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-5.27.1.tgz#315b59970c33933a5f62ca0f702789741dcedc7c"
|
||||
integrity sha512-wwDoavIeJI/Pwiavn32FMJ5dfptz0BAOKjSrj7EdU22QdP3gdk9+MZHdzzjxWURmVj0kc0XoQfsFgjln0toJaw==
|
||||
swagger-ui-react@^5.26.0:
|
||||
version "5.26.0"
|
||||
resolved "https://registry.yarnpkg.com/swagger-ui-react/-/swagger-ui-react-5.26.0.tgz#b15a903d556cc0ec2a56a969beb9d5bc9ea52910"
|
||||
integrity sha512-4e6bP9bdJyh+SqQW0lxulPn/SDno4+oWrKXsuon5Z9kjtV0zeoWEJ1c70Qxp8kN/c3caFwec8OyxDNhvo14pkw==
|
||||
dependencies:
|
||||
"@babel/runtime-corejs3" "^7.27.1"
|
||||
"@scarf/scarf" "=1.4.0"
|
||||
@@ -12348,15 +12382,15 @@ types-ramda@^0.30.0:
|
||||
dependencies:
|
||||
ts-toolbelt "^9.6.0"
|
||||
|
||||
typescript-eslint@^8.39.0:
|
||||
version "8.39.0"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.39.0.tgz#b19c1a925cf8566831ae3875d2881ee2349808a5"
|
||||
integrity sha512-lH8FvtdtzcHJCkMOKnN73LIn6SLTpoojgJqDAxPm1jCR14eWSGPX8ul/gggBdPMk/d5+u9V854vTYQ8T5jF/1Q==
|
||||
typescript-eslint@^8.37.0:
|
||||
version "8.37.0"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.37.0.tgz#2235ddfa40cdbdadb1afb05f8bda688a2294b4c2"
|
||||
integrity sha512-TnbEjzkE9EmcO0Q2zM+GE8NQLItNAJpMmED1BdgoBMYNdqMhzlbqfdSwiRlAzEK2pA9UzVW0gzaaIzXWg2BjfA==
|
||||
dependencies:
|
||||
"@typescript-eslint/eslint-plugin" "8.39.0"
|
||||
"@typescript-eslint/parser" "8.39.0"
|
||||
"@typescript-eslint/typescript-estree" "8.39.0"
|
||||
"@typescript-eslint/utils" "8.39.0"
|
||||
"@typescript-eslint/eslint-plugin" "8.37.0"
|
||||
"@typescript-eslint/parser" "8.37.0"
|
||||
"@typescript-eslint/typescript-estree" "8.37.0"
|
||||
"@typescript-eslint/utils" "8.37.0"
|
||||
|
||||
typescript@~5.8.3:
|
||||
version "5.8.3"
|
||||
@@ -12491,7 +12525,7 @@ unraw@^3.0.0:
|
||||
resolved "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz"
|
||||
integrity sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==
|
||||
|
||||
update-browserslist-db@^1.1.3:
|
||||
update-browserslist-db@^1.1.1, update-browserslist-db@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420"
|
||||
integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==
|
||||
@@ -12760,27 +12794,26 @@ webpack-merge@^6.0.1:
|
||||
flat "^5.0.2"
|
||||
wildcard "^2.0.1"
|
||||
|
||||
webpack-sources@^3.3.3:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723"
|
||||
integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==
|
||||
webpack-sources@^3.2.3:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
|
||||
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
|
||||
|
||||
webpack@^5.101.0, webpack@^5.88.1, webpack@^5.95.0:
|
||||
version "5.101.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.101.0.tgz#4b81407ffad9857f81ff03f872e3369b9198cc9d"
|
||||
integrity sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ==
|
||||
webpack@^5.88.1, webpack@^5.95.0, webpack@^5.99.9:
|
||||
version "5.99.9"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.99.9.tgz#d7de799ec17d0cce3c83b70744b4aedb537d8247"
|
||||
integrity sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==
|
||||
dependencies:
|
||||
"@types/eslint-scope" "^3.7.7"
|
||||
"@types/estree" "^1.0.8"
|
||||
"@types/estree" "^1.0.6"
|
||||
"@types/json-schema" "^7.0.15"
|
||||
"@webassemblyjs/ast" "^1.14.1"
|
||||
"@webassemblyjs/wasm-edit" "^1.14.1"
|
||||
"@webassemblyjs/wasm-parser" "^1.14.1"
|
||||
acorn "^8.15.0"
|
||||
acorn-import-phases "^1.0.3"
|
||||
acorn "^8.14.0"
|
||||
browserslist "^4.24.0"
|
||||
chrome-trace-event "^1.0.2"
|
||||
enhanced-resolve "^5.17.2"
|
||||
enhanced-resolve "^5.17.1"
|
||||
es-module-lexer "^1.2.1"
|
||||
eslint-scope "5.1.1"
|
||||
events "^3.2.0"
|
||||
@@ -12794,7 +12827,7 @@ webpack@^5.101.0, webpack@^5.88.1, webpack@^5.95.0:
|
||||
tapable "^2.1.1"
|
||||
terser-webpack-plugin "^5.3.11"
|
||||
watchpack "^2.4.1"
|
||||
webpack-sources "^3.3.3"
|
||||
webpack-sources "^3.2.3"
|
||||
|
||||
webpackbar@^6.0.1:
|
||||
version "6.0.1"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
apiVersion: v2
|
||||
appVersion: "5.0.0"
|
||||
appVersion: "4.1.2"
|
||||
description: Apache Superset is a modern, enterprise-ready business intelligence web application
|
||||
name: superset
|
||||
icon: https://artifacthub.io/image/68c1d717-0e97-491f-b046-754e46f46922@2x
|
||||
@@ -29,7 +29,7 @@ maintainers:
|
||||
- name: craig-rueda
|
||||
email: craig@craigrueda.com
|
||||
url: https://github.com/craig-rueda
|
||||
version: 0.15.0 # See [README](https://github.com/apache/superset/blob/master/helm/superset/README.md#versioning) for version details.
|
||||
version: 0.14.3
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
version: 13.4.4
|
||||
|
||||
@@ -23,7 +23,7 @@ NOTE: This file is generated by helm-docs: https://github.com/norwoodj/helm-docs
|
||||
|
||||
# superset
|
||||
|
||||

|
||||

|
||||
|
||||
Apache Superset is a modern, enterprise-ready business intelligence web application
|
||||
|
||||
@@ -336,6 +336,3 @@ On helm this can be set on `extraSecretEnv.SUPERSET_SECRET_KEY` or `configOverri
|
||||
| supersetWorker.topologySpreadConstraints | list | `[]` | TopologySpreadConstrains to be added to supersetWorker deployments |
|
||||
| tolerations | list | `[]` | |
|
||||
| topologySpreadConstraints | list | `[]` | TopologySpreadConstrains to be added to all deployments |
|
||||
|
||||
## Versioning
|
||||
This chart follows [semantic versioning](https://semver.org/). The chart version is independent of the Superset version. The chart version is incremented when there are changes to the chart itself, such as new features, bug fixes, or changes in configuration options. In addition to semver, the chart version is also incremented in the minor version when there is a breaking change in the Superset appVersion itself. When there are non-breaking changes in the Superset appVersion, the chart version is incremented in the patch version.
|
||||
|
||||
@@ -48,6 +48,3 @@ On helm this can be set on `extraSecretEnv.SUPERSET_SECRET_KEY` or `configOverri
|
||||
{{ template "chart.requirementsSection" . }}
|
||||
|
||||
{{ template "chart.valuesSection" . }}
|
||||
|
||||
## Versioning
|
||||
This chart follows [semantic versioning](https://semver.org/). The chart version is independent of the Superset version. The chart version is incremented when there are changes to the chart itself, such as new features, bug fixes, or changes in configuration options. In addition to semver, the chart version is also incremented in the minor version when there is a breaking change in the Superset appVersion itself. When there are non-breaking changes in the Superset appVersion, the chart version is incremented in the patch version.
|
||||
|
||||
@@ -79,13 +79,12 @@ dependencies = [
|
||||
"parsedatetime",
|
||||
"paramiko>=3.4.0",
|
||||
"pgsanity",
|
||||
"Pillow>=11.0.0, <12",
|
||||
"polyline>=2.0.0, <3.0",
|
||||
"pyparsing>=3.0.6, <4",
|
||||
"python-dateutil",
|
||||
"python-dotenv", # optional dependencies for Flask but required for Superset, see https://flask.palletsprojects.com/en/stable/installation/#optional-dependencies
|
||||
"python-geohash",
|
||||
"pyarrow>=16.1.0, <17", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693
|
||||
"pyarrow>=18.1.0, <19",
|
||||
"pyyaml>=6.0.0, <7.0.0",
|
||||
"PyJWT>=2.4.0, <3.0",
|
||||
"redis>=4.6.0, <5.0",
|
||||
@@ -112,7 +111,7 @@ athena = ["pyathena[pandas]>=2, <3"]
|
||||
aurora-data-api = ["preset-sqlalchemy-aurora-data-api>=0.2.8,<0.3"]
|
||||
bigquery = [
|
||||
"pandas-gbq>=0.19.1",
|
||||
"sqlalchemy-bigquery>=1.15.0",
|
||||
"sqlalchemy-bigquery>=1.6.1",
|
||||
"google-cloud-bigquery>=3.10.0",
|
||||
]
|
||||
clickhouse = ["clickhouse-connect>=0.5.14, <1.0"]
|
||||
@@ -182,7 +181,7 @@ tdengine = [
|
||||
"taos-ws-py>=0.3.8"
|
||||
]
|
||||
teradata = ["teradatasql>=16.20.0.23"]
|
||||
thumbnails = [] # deprecated, will be removed in 7.0
|
||||
thumbnails = ["Pillow>=10.0.1, <11"]
|
||||
vertica = ["sqlalchemy-vertica-python>=0.5.9, < 0.6"]
|
||||
netezza = ["nzalchemy>=11.0.2"]
|
||||
starrocks = ["starrocks>=1.0.0"]
|
||||
@@ -196,7 +195,6 @@ development = [
|
||||
"grpcio>=1.55.3",
|
||||
"openapi-spec-validator",
|
||||
"parameterized",
|
||||
"pip",
|
||||
"pre-commit",
|
||||
"progress>=1.5,<2",
|
||||
"psutil",
|
||||
@@ -401,7 +399,6 @@ authorized_licenses = [
|
||||
"isc license (iscl)",
|
||||
"isc license",
|
||||
"mit",
|
||||
"mit-cmu",
|
||||
"mozilla public license 2.0 (mpl 2.0)",
|
||||
"osi approved",
|
||||
"osi approved",
|
||||
|
||||
@@ -11,7 +11,9 @@ apispec==6.6.1
|
||||
apsw==3.50.1.0
|
||||
# via shillelagh
|
||||
async-timeout==4.0.3
|
||||
# via -r requirements/base.in
|
||||
# via
|
||||
# -r requirements/base.in
|
||||
# redis
|
||||
attrs==25.3.0
|
||||
# via
|
||||
# cattrs
|
||||
@@ -97,6 +99,11 @@ email-validator==2.2.0
|
||||
# via flask-appbuilder
|
||||
et-xmlfile==2.0.0
|
||||
# via openpyxl
|
||||
exceptiongroup==1.3.0
|
||||
# via
|
||||
# cattrs
|
||||
# trio
|
||||
# trio-websocket
|
||||
flask==2.3.3
|
||||
# via
|
||||
# apache-superset (pyproject.toml)
|
||||
@@ -154,6 +161,7 @@ greenlet==3.1.1
|
||||
# via
|
||||
# apache-superset (pyproject.toml)
|
||||
# shillelagh
|
||||
# sqlalchemy
|
||||
gunicorn==23.0.0
|
||||
# via apache-superset (pyproject.toml)
|
||||
h11==0.16.0
|
||||
@@ -266,8 +274,6 @@ parsedatetime==2.6
|
||||
# via apache-superset (pyproject.toml)
|
||||
pgsanity==0.2.9
|
||||
# via apache-superset (pyproject.toml)
|
||||
pillow==11.3.0
|
||||
# via apache_superset (pyproject.toml)
|
||||
platformdirs==4.3.8
|
||||
# via requests-cache
|
||||
ply==3.11
|
||||
@@ -278,7 +284,7 @@ prison==0.2.1
|
||||
# via flask-appbuilder
|
||||
prompt-toolkit==3.0.51
|
||||
# via click-repl
|
||||
pyarrow==16.1.0
|
||||
pyarrow==18.1.0
|
||||
# via apache-superset (pyproject.toml)
|
||||
pyasn1==0.6.1
|
||||
# via
|
||||
@@ -312,7 +318,7 @@ python-dateutil==2.9.0.post0
|
||||
# holidays
|
||||
# pandas
|
||||
# shillelagh
|
||||
python-dotenv==1.1.0
|
||||
python-dotenv==1.1.1
|
||||
# via apache-superset (pyproject.toml)
|
||||
python-geohash==0.8.5
|
||||
# via apache-superset (pyproject.toml)
|
||||
@@ -397,9 +403,11 @@ typing-extensions==4.14.0
|
||||
# apache-superset (pyproject.toml)
|
||||
# alembic
|
||||
# cattrs
|
||||
# exceptiongroup
|
||||
# limits
|
||||
# pyopenssl
|
||||
# referencing
|
||||
# rich
|
||||
# selenium
|
||||
# shillelagh
|
||||
tzdata==2025.2
|
||||
|
||||
@@ -20,6 +20,10 @@ apsw==3.50.1.0
|
||||
# shillelagh
|
||||
astroid==3.3.10
|
||||
# via pylint
|
||||
async-timeout==4.0.3
|
||||
# via
|
||||
# -c requirements/base.txt
|
||||
# redis
|
||||
attrs==25.3.0
|
||||
# via
|
||||
# -c requirements/base.txt
|
||||
@@ -176,6 +180,13 @@ et-xmlfile==2.0.0
|
||||
# via
|
||||
# -c requirements/base.txt
|
||||
# openpyxl
|
||||
exceptiongroup==1.3.0
|
||||
# via
|
||||
# -c requirements/base.txt
|
||||
# cattrs
|
||||
# pytest
|
||||
# trio
|
||||
# trio-websocket
|
||||
filelock==3.12.2
|
||||
# via virtualenv
|
||||
flask==2.3.3
|
||||
@@ -313,6 +324,7 @@ greenlet==3.1.1
|
||||
# apache-superset
|
||||
# gevent
|
||||
# shillelagh
|
||||
# sqlalchemy
|
||||
grpcio==1.71.0
|
||||
# via
|
||||
# apache-superset
|
||||
@@ -537,12 +549,10 @@ pgsanity==0.2.9
|
||||
# via
|
||||
# -c requirements/base.txt
|
||||
# apache-superset
|
||||
pillow==11.3.0
|
||||
pillow==10.3.0
|
||||
# via
|
||||
# apache-superset
|
||||
# matplotlib
|
||||
pip==25.1.1
|
||||
# via apache-superset
|
||||
platformdirs==4.3.8
|
||||
# via
|
||||
# -c requirements/base.txt
|
||||
@@ -588,7 +598,7 @@ psutil==6.1.0
|
||||
# via apache-superset
|
||||
psycopg2-binary==2.9.6
|
||||
# via apache-superset
|
||||
pyarrow==16.1.0
|
||||
pyarrow==18.1.0
|
||||
# via
|
||||
# -c requirements/base.txt
|
||||
# apache-superset
|
||||
@@ -672,7 +682,7 @@ python-dateutil==2.9.0.post0
|
||||
# pyhive
|
||||
# shillelagh
|
||||
# trino
|
||||
python-dotenv==1.1.0
|
||||
python-dotenv==1.1.1
|
||||
# via
|
||||
# -c requirements/base.txt
|
||||
# apache-superset
|
||||
@@ -797,7 +807,7 @@ sqlalchemy==1.4.54
|
||||
# shillelagh
|
||||
# sqlalchemy-bigquery
|
||||
# sqlalchemy-utils
|
||||
sqlalchemy-bigquery==1.15.0
|
||||
sqlalchemy-bigquery==1.12.0
|
||||
# via apache-superset
|
||||
sqlalchemy-utils==0.38.3
|
||||
# via
|
||||
@@ -820,6 +830,11 @@ tabulate==0.9.0
|
||||
# via
|
||||
# -c requirements/base.txt
|
||||
# apache-superset
|
||||
tomli==2.2.1
|
||||
# via
|
||||
# coverage
|
||||
# pylint
|
||||
# pytest
|
||||
tomlkit==0.13.3
|
||||
# via pylint
|
||||
tqdm==4.67.1
|
||||
@@ -842,10 +857,13 @@ typing-extensions==4.14.0
|
||||
# -c requirements/base.txt
|
||||
# alembic
|
||||
# apache-superset
|
||||
# astroid
|
||||
# cattrs
|
||||
# exceptiongroup
|
||||
# limits
|
||||
# pyopenssl
|
||||
# referencing
|
||||
# rich
|
||||
# selenium
|
||||
# shillelagh
|
||||
tzdata==2025.2
|
||||
|
||||
@@ -33,4 +33,4 @@ superset load-test-users
|
||||
|
||||
echo "Running tests"
|
||||
|
||||
pytest --durations-min=2 --cov-report= --cov=superset ./tests/integration_tests "$@"
|
||||
pytest --durations-min=2 --maxfail=1 --cov-report= --cov=superset ./tests/integration_tests "$@"
|
||||
|
||||
@@ -403,7 +403,6 @@ module.exports = {
|
||||
'theme-colors/no-literal-colors': 'error',
|
||||
'icons/no-fa-icons-usage': 'error',
|
||||
'i18n-strings/no-template-vars': ['error', true],
|
||||
'i18n-strings/sentence-case-buttons': 'error',
|
||||
camelcase: [
|
||||
'error',
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import { LOGIN } from 'cypress/utils/urls';
|
||||
|
||||
function interceptLogin() {
|
||||
cy.intercept('POST', '**/login/').as('login');
|
||||
cy.intercept('POST', '/login/').as('login');
|
||||
}
|
||||
|
||||
describe('Login view', () => {
|
||||
|
||||
@@ -94,12 +94,67 @@ describe('Charts list', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('list mode', () => {
|
||||
before(() => {
|
||||
visitChartList();
|
||||
setGridMode('list');
|
||||
});
|
||||
|
||||
it('should load rows in list mode', () => {
|
||||
cy.getBySel('listview-table').should('be.visible');
|
||||
cy.getBySel('sort-header').eq(1).contains('Name');
|
||||
cy.getBySel('sort-header').eq(2).contains('Type');
|
||||
cy.getBySel('sort-header').eq(3).contains('Dataset');
|
||||
cy.getBySel('sort-header').eq(4).contains('On dashboards');
|
||||
cy.getBySel('sort-header').eq(5).contains('Owners');
|
||||
cy.getBySel('sort-header').eq(6).contains('Last modified');
|
||||
cy.getBySel('sort-header').eq(7).contains('Actions');
|
||||
});
|
||||
|
||||
it('should bulk select in list mode', () => {
|
||||
toggleBulkSelect();
|
||||
cy.get('[aria-label="Select all"]').click();
|
||||
cy.get('input[type="checkbox"]:checked').should('have.length', 26);
|
||||
cy.getBySel('bulk-select-copy').contains('25 Selected');
|
||||
cy.getBySel('bulk-select-action')
|
||||
.should('have.length', 2)
|
||||
.then($btns => {
|
||||
expect($btns).to.contain('Delete');
|
||||
expect($btns).to.contain('Export');
|
||||
});
|
||||
cy.getBySel('bulk-select-deselect-all').click();
|
||||
cy.get('input[type="checkbox"]:checked').should('have.length', 0);
|
||||
cy.getBySel('bulk-select-copy').contains('0 Selected');
|
||||
cy.getBySel('bulk-select-action').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('card mode', () => {
|
||||
before(() => {
|
||||
visitChartList();
|
||||
setGridMode('card');
|
||||
});
|
||||
|
||||
it('should load rows in card mode', () => {
|
||||
cy.getBySel('listview-table').should('not.exist');
|
||||
cy.getBySel('styled-card').should('have.length', 25);
|
||||
});
|
||||
|
||||
it('should bulk select in card mode', () => {
|
||||
toggleBulkSelect();
|
||||
cy.getBySel('styled-card').click({ multiple: true });
|
||||
cy.getBySel('bulk-select-copy').contains('25 Selected');
|
||||
cy.getBySel('bulk-select-action')
|
||||
.should('have.length', 2)
|
||||
.then($btns => {
|
||||
expect($btns).to.contain('Delete');
|
||||
expect($btns).to.contain('Export');
|
||||
});
|
||||
cy.getBySel('bulk-select-deselect-all').click();
|
||||
cy.getBySel('bulk-select-copy').contains('0 Selected');
|
||||
cy.getBySel('bulk-select-action').should('not.exist');
|
||||
});
|
||||
|
||||
it('should preserve other filters when sorting', () => {
|
||||
cy.getBySel('styled-card').should('have.length', 25);
|
||||
setFilter('Type', 'Big Number');
|
||||
|
||||
@@ -31,52 +31,6 @@ import {
|
||||
interceptFormDataKey,
|
||||
} from '../explore/utils';
|
||||
|
||||
const interceptDrillInfo = () => {
|
||||
cy.intercept('GET', '**/api/v1/dataset/*/drill_info/*', {
|
||||
statusCode: 200,
|
||||
body: {
|
||||
result: {
|
||||
id: 1,
|
||||
changed_on_humanized: '2 days ago',
|
||||
created_on_humanized: 'a week ago',
|
||||
table_name: 'birth_names',
|
||||
changed_by: {
|
||||
first_name: 'Admin',
|
||||
last_name: 'User',
|
||||
},
|
||||
created_by: {
|
||||
first_name: 'Admin',
|
||||
last_name: 'User',
|
||||
},
|
||||
owners: [
|
||||
{
|
||||
first_name: 'Admin',
|
||||
last_name: 'User',
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
column_name: 'gender',
|
||||
verbose_name: null,
|
||||
},
|
||||
{
|
||||
column_name: 'state',
|
||||
verbose_name: null,
|
||||
},
|
||||
{
|
||||
column_name: 'name',
|
||||
verbose_name: null,
|
||||
},
|
||||
{
|
||||
column_name: 'ds',
|
||||
verbose_name: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}).as('drillInfo');
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find('[data-test="close-drill-by-modal"]').length) {
|
||||
@@ -108,20 +62,14 @@ const drillBy = (targetDrillByColumn: string, isLegacy = false) => {
|
||||
|
||||
cy.get(
|
||||
'.ant-dropdown-menu-submenu:not(.ant-dropdown-menu-submenu-hidden) [data-test="drill-by-submenu"]',
|
||||
{ timeout: 15000 },
|
||||
)
|
||||
.should('be.visible')
|
||||
.find('[role="menuitem"]')
|
||||
.contains(new RegExp(`^${targetDrillByColumn}$`))
|
||||
.click();
|
||||
|
||||
cy.get(
|
||||
'.ant-dropdown-menu-submenu:not(.ant-dropdown-menu-submenu-hidden) [data-test="drill-by-submenu"]',
|
||||
).trigger('mouseout', { clientX: 0, clientY: 0, force: true });
|
||||
|
||||
cy.get(
|
||||
'.ant-dropdown-menu-submenu:not(.ant-dropdown-menu-submenu-hidden) [data-test="drill-by-submenu"]',
|
||||
).should('not.exist');
|
||||
.then($el => {
|
||||
cy.wrap($el)
|
||||
.contains(new RegExp(`^${targetDrillByColumn}$`))
|
||||
.trigger('keydown', { keyCode: 13, which: 13, force: true });
|
||||
});
|
||||
|
||||
if (isLegacy) {
|
||||
return cy.wait('@legacyData');
|
||||
@@ -282,19 +230,17 @@ describe('Drill by modal', () => {
|
||||
closeModal();
|
||||
});
|
||||
before(() => {
|
||||
interceptDrillInfo();
|
||||
cy.visit(SUPPORTED_CHARTS_DASHBOARD);
|
||||
});
|
||||
|
||||
describe('Modal actions + Table', () => {
|
||||
before(() => {
|
||||
closeModal();
|
||||
interceptDrillInfo();
|
||||
openTopLevelTab('Tier 1');
|
||||
SUPPORTED_TIER1_CHARTS.forEach(waitForChartLoad);
|
||||
});
|
||||
|
||||
it.only('opens the modal from the context menu', () => {
|
||||
it('opens the modal from the context menu', () => {
|
||||
openTableContextMenu('boy');
|
||||
drillBy('state').then(intercepted => {
|
||||
verifyExpectedFormData(intercepted, {
|
||||
@@ -438,7 +384,6 @@ describe('Drill by modal', () => {
|
||||
describe('Tier 1 charts', () => {
|
||||
before(() => {
|
||||
closeModal();
|
||||
interceptDrillInfo();
|
||||
openTopLevelTab('Tier 1');
|
||||
SUPPORTED_TIER1_CHARTS.forEach(waitForChartLoad);
|
||||
});
|
||||
@@ -602,7 +547,6 @@ describe('Drill by modal', () => {
|
||||
describe('Tier 2 charts', () => {
|
||||
before(() => {
|
||||
closeModal();
|
||||
interceptDrillInfo();
|
||||
openTopLevelTab('Tier 2');
|
||||
SUPPORTED_TIER2_CHARTS.forEach(waitForChartLoad);
|
||||
});
|
||||
|
||||
@@ -155,7 +155,7 @@ describe('Horizontal FilterBar', () => {
|
||||
]);
|
||||
setFilterBarOrientation('horizontal');
|
||||
|
||||
cy.get('.filter-item-wrapper').should('have.length', 4);
|
||||
cy.get('.filter-item-wrapper').should('have.length', 3);
|
||||
openMoreFilters();
|
||||
cy.getBySel('form-item-value').should('have.length', 12);
|
||||
cy.getBySel('filter-control-name').contains('test_3').should('be.visible');
|
||||
|
||||
@@ -160,74 +160,6 @@ describe('Native filters', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Dependent filter selects first item based on parent filter selection', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'region', column: 'region', datasetId: 2 },
|
||||
{ name: 'country_name', column: 'country_name', datasetId: 2 },
|
||||
]);
|
||||
|
||||
enterNativeFilterEditModal();
|
||||
|
||||
selectFilter(0);
|
||||
cy.get(nativeFilters.filterConfigurationSections.displayedSection).within(
|
||||
() => {
|
||||
cy.contains('Select first filter value by default')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
},
|
||||
);
|
||||
cy.get(nativeFilters.filterConfigurationSections.displayedSection).within(
|
||||
() => {
|
||||
cy.contains('Can select multiple values ')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
},
|
||||
);
|
||||
|
||||
selectFilter(1);
|
||||
cy.get(nativeFilters.filterConfigurationSections.displayedSection).within(
|
||||
() => {
|
||||
cy.contains('Values are dependent on other filters')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
},
|
||||
);
|
||||
cy.get(nativeFilters.filterConfigurationSections.displayedSection).within(
|
||||
() => {
|
||||
cy.contains('Can select multiple values ')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
},
|
||||
);
|
||||
addParentFilterWithValue(0, testItems.topTenChart.filterColumnRegion);
|
||||
cy.get(nativeFilters.filterConfigurationSections.displayedSection).within(
|
||||
() => {
|
||||
cy.contains('Select first filter value by default')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
},
|
||||
);
|
||||
|
||||
// cannot use saveNativeFilterSettings because there is a bug which
|
||||
// sometimes does not allow charts to load when enabling the 'Select first filter value by default'
|
||||
// to be saved when using dependent filters so,
|
||||
// you reload the window.
|
||||
cy.get(nativeFilters.modal.footer)
|
||||
.contains('Save')
|
||||
.should('be.visible')
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(nativeFilters.modal.container).should('not.exist');
|
||||
cy.reload();
|
||||
|
||||
applyNativeFilterValueWithIndex(0, 'North America');
|
||||
|
||||
// Check that dependent filter auto-selects the first item
|
||||
cy.get(nativeFilters.filterFromDashboardView.filterContent)
|
||||
.eq(1)
|
||||
.should('contain.text', 'Bermuda');
|
||||
});
|
||||
|
||||
it('User can create filter depend on 2 other filters', () => {
|
||||
prepareDashboardFilters([
|
||||
{ name: 'region', column: 'region', datasetId: 2 },
|
||||
@@ -343,7 +275,7 @@ describe('Native filters', () => {
|
||||
it('User can delete a native filter', () => {
|
||||
enterNativeFilterEditModal(false);
|
||||
cy.get(nativeFilters.filtersList.removeIcon).first().click();
|
||||
cy.contains('Restore filter').should('not.exist', { timeout: 10000 });
|
||||
cy.contains('Restore Filter').should('not.exist', { timeout: 10000 });
|
||||
});
|
||||
|
||||
it('User can cancel creating a new filter', () => {
|
||||
|
||||
@@ -68,13 +68,11 @@ function verifyDashboardSearch() {
|
||||
function verifyDashboardLink() {
|
||||
interceptDashboardGet();
|
||||
openDashboardsAddedTo();
|
||||
cy.get('.ant-dropdown-menu-submenu-popup').trigger('mouseover', {
|
||||
force: true,
|
||||
});
|
||||
cy.get('.ant-dropdown-menu-submenu-popup').trigger('mouseover');
|
||||
cy.get('.ant-dropdown-menu-submenu-popup a')
|
||||
.first()
|
||||
.invoke('removeAttr', 'target')
|
||||
.click({ force: true });
|
||||
.click();
|
||||
cy.wait('@get');
|
||||
}
|
||||
|
||||
|
||||
20
superset-frontend/cypress-base/package-lock.json
generated
20
superset-frontend/cypress-base/package-lock.json
generated
@@ -10227,11 +10227,14 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.4.tgz",
|
||||
"integrity": "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==",
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
||||
"integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
|
||||
"dependencies": {
|
||||
"rimraf": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.14"
|
||||
"node": ">=8.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
@@ -18595,9 +18598,12 @@
|
||||
"peer": true
|
||||
},
|
||||
"tmp": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.4.tgz",
|
||||
"integrity": "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ=="
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
||||
"integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
|
||||
"requires": {
|
||||
"rimraf": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
|
||||
@@ -41,7 +41,7 @@ module.exports = {
|
||||
context.report({
|
||||
node,
|
||||
message:
|
||||
"Don't use variables in translation string templates. Flask-babel is a static translation service, so it can't handle strings that include variables",
|
||||
"Don't use variables in translation string templates. Flask-babel is a static translation service, so it can’t handle strings that include variables",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -52,67 +52,5 @@ module.exports = {
|
||||
};
|
||||
},
|
||||
},
|
||||
'sentence-case-buttons': {
|
||||
create(context) {
|
||||
function isTitleCase(str) {
|
||||
// Match "Delete Dataset", "Create Chart", etc. (2+ title-cased words)
|
||||
return /^[A-Z][a-z]+(\s+[A-Z][a-z]*)+$/.test(str);
|
||||
}
|
||||
|
||||
function isButtonContext(node) {
|
||||
const { parent } = node;
|
||||
if (!parent) return false;
|
||||
|
||||
// Check for button-specific props
|
||||
if (parent.type === 'Property') {
|
||||
const key = parent.key.name;
|
||||
return [
|
||||
'primaryButtonName',
|
||||
'secondaryButtonName',
|
||||
'confirmButtonText',
|
||||
'cancelButtonText',
|
||||
].includes(key);
|
||||
}
|
||||
|
||||
// Check for Button components
|
||||
if (parent.type === 'JSXExpressionContainer') {
|
||||
const jsx = parent.parent;
|
||||
if (jsx?.type === 'JSXElement') {
|
||||
const elementName = jsx.openingElement.name.name;
|
||||
return elementName === 'Button';
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function handler(node) {
|
||||
if (node.arguments.length) {
|
||||
const firstArg = node.arguments[0];
|
||||
if (
|
||||
firstArg.type === 'Literal' &&
|
||||
typeof firstArg.value === 'string'
|
||||
) {
|
||||
const text = firstArg.value;
|
||||
|
||||
if (isButtonContext(node) && isTitleCase(text)) {
|
||||
const sentenceCase = text
|
||||
.toLowerCase()
|
||||
.replace(/^\w/, c => c.toUpperCase());
|
||||
context.report({
|
||||
node: firstArg,
|
||||
message: `Button text should use sentence case: "${text}" should be "${sentenceCase}"`,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
"CallExpression[callee.name='t']": handler,
|
||||
"CallExpression[callee.name='tn']": handler,
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
3458
superset-frontend/package-lock.json
generated
3458
superset-frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "superset",
|
||||
"version": "6.0.0",
|
||||
"version": "0.0.0-dev",
|
||||
"description": "Superset is a data exploration platform designed to be visual, intuitive, and interactive.",
|
||||
"keywords": [
|
||||
"big",
|
||||
@@ -88,7 +88,7 @@
|
||||
"@reduxjs/toolkit": "^1.9.3",
|
||||
"@rjsf/core": "^5.21.1",
|
||||
"@rjsf/utils": "^5.24.3",
|
||||
"@rjsf/validator-ajv8": "^5.24.12",
|
||||
"@rjsf/validator-ajv8": "^5.24.9",
|
||||
"@scarf/scarf": "^1.4.0",
|
||||
"@superset-ui/chart-controls": "file:./packages/superset-ui-chart-controls",
|
||||
"@superset-ui/core": "file:./packages/superset-ui-core",
|
||||
@@ -121,13 +121,15 @@
|
||||
"@visx/scale": "^3.5.0",
|
||||
"@visx/tooltip": "^3.0.0",
|
||||
"@visx/xychart": "^3.5.1",
|
||||
"ag-grid-community": "33.1.1",
|
||||
"ag-grid-react": "33.1.1",
|
||||
"antd": "^5.24.6",
|
||||
"chrono-node": "^2.7.8",
|
||||
"classnames": "^2.2.5",
|
||||
"d3-color": "^3.1.0",
|
||||
"d3-scale": "^2.1.2",
|
||||
"dayjs": "^1.11.13",
|
||||
"dom-to-image-more": "^3.6.0",
|
||||
"dom-to-image-more": "^3.2.0",
|
||||
"dom-to-pdf": "^0.3.2",
|
||||
"echarts": "^5.6.0",
|
||||
"emotion-rgba": "0.0.12",
|
||||
@@ -142,7 +144,7 @@
|
||||
"geostyler-qgis-parser": "2.0.1",
|
||||
"geostyler-style": "7.5.0",
|
||||
"geostyler-wfs-parser": "^2.0.3",
|
||||
"googleapis": "^154.1.0",
|
||||
"googleapis": "^130.0.0",
|
||||
"immer": "^10.1.1",
|
||||
"interweave": "^13.1.0",
|
||||
"jquery": "^3.7.1",
|
||||
@@ -165,6 +167,7 @@
|
||||
"re-resizable": "^6.10.1",
|
||||
"react": "^17.0.2",
|
||||
"react-checkbox-tree": "^1.8.0",
|
||||
"react-color": "^2.13.8",
|
||||
"react-diff-viewer-continued": "^3.4.0",
|
||||
"react-dnd": "^11.1.3",
|
||||
"react-dnd-html5-backend": "^11.1.3",
|
||||
@@ -173,7 +176,7 @@
|
||||
"react-hot-loader": "^4.13.1",
|
||||
"react-intersection-observer": "^9.16.0",
|
||||
"react-json-tree": "^0.20.0",
|
||||
"react-lines-ellipsis": "^0.16.1",
|
||||
"react-lines-ellipsis": "^0.15.4",
|
||||
"react-loadable": "^5.5.0",
|
||||
"react-redux": "^7.2.9",
|
||||
"react-resize-detector": "^7.1.2",
|
||||
@@ -205,7 +208,7 @@
|
||||
"devDependencies": {
|
||||
"@applitools/eyes-storybook": "^3.55.6",
|
||||
"@babel/cli": "^7.27.2",
|
||||
"@babel/compat-data": "^7.28.0",
|
||||
"@babel/compat-data": "^7.26.8",
|
||||
"@babel/core": "^7.26.0",
|
||||
"@babel/eslint-parser": "^7.25.9",
|
||||
"@babel/node": "^7.22.6",
|
||||
@@ -213,11 +216,11 @@
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.26.3",
|
||||
"@babel/plugin-transform-runtime": "^7.27.1",
|
||||
"@babel/preset-env": "^7.27.2",
|
||||
"@babel/preset-react": "^7.27.1",
|
||||
"@babel/preset-react": "^7.26.3",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@babel/register": "^7.23.7",
|
||||
"@babel/runtime": "^7.28.2",
|
||||
"@babel/runtime-corejs3": "^7.28.2",
|
||||
"@babel/runtime": "^7.26.0",
|
||||
"@babel/runtime-corejs3": "^7.26.0",
|
||||
"@babel/types": "^7.26.9",
|
||||
"@cypress/react": "^8.0.2",
|
||||
"@emotion/babel-plugin": "^11.13.5",
|
||||
@@ -240,6 +243,7 @@
|
||||
"@testing-library/react": "^12.1.5",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/classnames": "^2.2.10",
|
||||
"@types/dom-to-image": "^2.6.7",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/js-levenshtein": "^1.1.3",
|
||||
@@ -281,7 +285,7 @@
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-prettier": "^7.2.0",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-import-resolver-typescript": "^4.4.4",
|
||||
"eslint-import-resolver-typescript": "^3.7.0",
|
||||
"eslint-plugin-cypress": "^3.6.0",
|
||||
"eslint-plugin-file-progress": "^1.5.0",
|
||||
"eslint-plugin-icons": "file:eslint-rules/eslint-plugin-icons",
|
||||
@@ -327,7 +331,7 @@
|
||||
"ts-jest": "^29.4.0",
|
||||
"ts-loader": "^9.5.1",
|
||||
"tscw-config": "^1.1.2",
|
||||
"tsx": "^4.20.3",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "5.4.5",
|
||||
"vm-browserify": "^1.1.2",
|
||||
"webpack": "^5.99.9",
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
export interface <%= packageLabel %>StylesProps {
|
||||
height: number;
|
||||
width: number;
|
||||
headerFontSize: 'fontSizeSM' | 'fontSize' | 'fontSizeLG' | 'fontSizeXL' | 'fontSizeHeading1' | 'fontSizeHeading2' | 'fontSizeHeading3' | 'fontSizeHeading4' | 'fontSizeHeading5';
|
||||
headerFontSize: keyof typeof supersetTheme.typography.sizes;
|
||||
boldText: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"devDependencies": {
|
||||
"cross-env": "^7.0.3",
|
||||
"fs-extra": "^11.3.0",
|
||||
"jest": "^30.0.5",
|
||||
"jest": "^30.0.2",
|
||||
"yeoman-test": "^10.1.1"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -24,7 +24,7 @@ import { css, styled, useTheme, t } from '@superset-ui/core';
|
||||
|
||||
const StyledCalculatorIcon = styled(CalculatorOutlined)`
|
||||
${({ theme }) => css`
|
||||
color: ${theme.colorIcon};
|
||||
color: ${theme.colors.grayscale.base};
|
||||
font-size: ${theme.fontSizeSM}px;
|
||||
& svg {
|
||||
margin-left: ${theme.sizeUnit}px;
|
||||
|
||||
@@ -36,19 +36,18 @@ export const renameOperator: PostProcessingFactory<PostProcessingRename> = (
|
||||
const columns = ensureIsArray(
|
||||
queryObject.series_columns || queryObject.columns,
|
||||
);
|
||||
const timeOffsets = ensureIsArray(formData.time_compare);
|
||||
const { truncate_metric } = formData;
|
||||
const xAxisLabel = getXAxisLabel(formData);
|
||||
const isTimeComparisonValue = isTimeComparison(formData, queryObject);
|
||||
|
||||
// remove or rename top level of column name(metric name) in the MultiIndex when
|
||||
// 1) at least 1 metric
|
||||
// 2) dimension exist or multiple time shift metrics exist
|
||||
// 2) dimension exist
|
||||
// 3) xAxis exist
|
||||
// 4) truncate_metric in form_data and truncate_metric is true
|
||||
if (
|
||||
metrics.length > 0 &&
|
||||
(columns.length > 0 || timeOffsets.length > 1) &&
|
||||
columns.length > 0 &&
|
||||
xAxisLabel &&
|
||||
truncate_metric !== undefined &&
|
||||
!!truncate_metric
|
||||
@@ -85,8 +84,7 @@ export const renameOperator: PostProcessingFactory<PostProcessingRename> = (
|
||||
ComparisonType.Percentage,
|
||||
ComparisonType.Ratio,
|
||||
].includes(formData.comparison_type) &&
|
||||
metrics.length === 1 &&
|
||||
renamePairs.length === 0
|
||||
metrics.length === 1
|
||||
) {
|
||||
renamePairs.push([getMetricLabel(metrics[0]), null]);
|
||||
}
|
||||
|
||||
@@ -41,53 +41,6 @@ import {
|
||||
import { checkColumnType } from '../utils/checkColumnType';
|
||||
import { isSortable } from '../utils/isSortable';
|
||||
|
||||
// Aggregation choices with computation methods for plugins and controls
|
||||
export const aggregationChoices = {
|
||||
raw: {
|
||||
label: 'Overall value',
|
||||
compute: (data: number[]) => {
|
||||
if (!data.length) return null;
|
||||
return data[0];
|
||||
},
|
||||
},
|
||||
LAST_VALUE: {
|
||||
label: 'Last Value',
|
||||
compute: (data: number[]) => {
|
||||
if (!data.length) return null;
|
||||
return data[0];
|
||||
},
|
||||
},
|
||||
sum: {
|
||||
label: 'Total (Sum)',
|
||||
compute: (data: number[]) =>
|
||||
data.length ? data.reduce((a, b) => a + b, 0) : null,
|
||||
},
|
||||
mean: {
|
||||
label: 'Average (Mean)',
|
||||
compute: (data: number[]) =>
|
||||
data.length ? data.reduce((a, b) => a + b, 0) / data.length : null,
|
||||
},
|
||||
min: {
|
||||
label: 'Minimum',
|
||||
compute: (data: number[]) => (data.length ? Math.min(...data) : null),
|
||||
},
|
||||
max: {
|
||||
label: 'Maximum',
|
||||
compute: (data: number[]) => (data.length ? Math.max(...data) : null),
|
||||
},
|
||||
median: {
|
||||
label: 'Median',
|
||||
compute: (data: number[]) => {
|
||||
if (!data.length) return null;
|
||||
const sorted = [...data].sort((a, b) => a - b);
|
||||
const mid = Math.floor(sorted.length / 2);
|
||||
return sorted.length % 2 === 0
|
||||
? (sorted[mid - 1] + sorted[mid]) / 2
|
||||
: sorted[mid];
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const contributionModeControl = {
|
||||
name: 'contributionMode',
|
||||
config: {
|
||||
@@ -116,12 +69,17 @@ export const aggregationControl = {
|
||||
default: 'LAST_VALUE',
|
||||
clearable: false,
|
||||
renderTrigger: false,
|
||||
choices: Object.entries(aggregationChoices).map(([value, { label }]) => [
|
||||
value,
|
||||
t(label),
|
||||
]),
|
||||
choices: [
|
||||
['raw', t('None')],
|
||||
['LAST_VALUE', t('Last Value')],
|
||||
['sum', t('Total (Sum)')],
|
||||
['mean', t('Average (Mean)')],
|
||||
['min', t('Minimum')],
|
||||
['max', t('Maximum')],
|
||||
['median', t('Median')],
|
||||
],
|
||||
description: t(
|
||||
'Method to compute the displayed value. "Overall value" calculates a single metric across the entire filtered time period, ideal for non-additive metrics like ratios, averages, or distinct counts. Other methods operate over the time series data points.',
|
||||
'Aggregation method used to compute the Big Number from the Trendline.For non-additive metrics like ratios, averages, distinct counts, etc use NONE.',
|
||||
),
|
||||
provideFormDataToProps: true,
|
||||
mapStateToProps: ({ form_data }: ControlPanelState) => ({
|
||||
|
||||
@@ -177,7 +177,6 @@ const granularity: SharedControlConfig<'SelectControl'> = {
|
||||
'can type and use simple natural language as in `10 seconds`, ' +
|
||||
'`1 day` or `56 weeks`',
|
||||
),
|
||||
sortComparator: () => 0, // Disable frontend sorting to preserve backend order
|
||||
};
|
||||
|
||||
const time_grain_sqla: SharedControlConfig<'SelectControl'> = {
|
||||
@@ -205,7 +204,6 @@ const time_grain_sqla: SharedControlConfig<'SelectControl'> = {
|
||||
choices: (datasource as Dataset)?.time_grain_sqla || [],
|
||||
}),
|
||||
visibility: displayTimeRelatedControls,
|
||||
sortComparator: () => 0, // Disable frontend sorting to preserve backend order
|
||||
};
|
||||
|
||||
const time_range: SharedControlConfig<'DateFilterControl'> = {
|
||||
|
||||
@@ -29,4 +29,3 @@ export * from './getStandardizedControls';
|
||||
export * from './getTemporalColumns';
|
||||
export * from './displayTimeRelatedControls';
|
||||
export * from './colorControls';
|
||||
export * from './metricColumnFilter';
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { QueryFormMetric, SqlaFormData } from '@superset-ui/core';
|
||||
import {
|
||||
shouldSkipMetricColumn,
|
||||
isRegularMetric,
|
||||
isPercentMetric,
|
||||
} from './metricColumnFilter';
|
||||
|
||||
const createMetric = (label: string): QueryFormMetric =>
|
||||
({
|
||||
label,
|
||||
expressionType: 'SIMPLE',
|
||||
column: { column_name: label },
|
||||
aggregate: 'SUM',
|
||||
}) as QueryFormMetric;
|
||||
|
||||
describe('metricColumnFilter', () => {
|
||||
const createFormData = (
|
||||
metrics: string[],
|
||||
percentMetrics: string[],
|
||||
): SqlaFormData =>
|
||||
({
|
||||
datasource: 'test_datasource',
|
||||
viz_type: 'table',
|
||||
metrics: metrics.map(createMetric),
|
||||
percent_metrics: percentMetrics.map(createMetric),
|
||||
}) as SqlaFormData;
|
||||
|
||||
describe('shouldSkipMetricColumn', () => {
|
||||
it('should skip unprefixed percent metric columns if prefixed version exists', () => {
|
||||
const colnames = ['metric1', '%metric1'];
|
||||
const formData = createFormData([], ['metric1']);
|
||||
|
||||
const result = shouldSkipMetricColumn({
|
||||
colname: 'metric1',
|
||||
colnames,
|
||||
formData,
|
||||
});
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should not skip if column is also a regular metric', () => {
|
||||
const colnames = ['metric1', '%metric1'];
|
||||
const formData = createFormData(['metric1'], ['metric1']);
|
||||
|
||||
const result = shouldSkipMetricColumn({
|
||||
colname: 'metric1',
|
||||
colnames,
|
||||
formData,
|
||||
});
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should not skip if column starts with %', () => {
|
||||
const colnames = ['%metric1'];
|
||||
const formData = createFormData(['metric1'], []);
|
||||
|
||||
const result = shouldSkipMetricColumn({
|
||||
colname: '%metric1',
|
||||
colnames,
|
||||
formData,
|
||||
});
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should not skip if no prefixed version exists', () => {
|
||||
const colnames = ['metric1'];
|
||||
const formData = createFormData([], ['metric1']);
|
||||
|
||||
const result = shouldSkipMetricColumn({
|
||||
colname: 'metric1',
|
||||
colnames,
|
||||
formData,
|
||||
});
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isRegularMetric', () => {
|
||||
it('should return true for regular metrics', () => {
|
||||
const formData = createFormData(['metric1', 'metric2'], []);
|
||||
expect(isRegularMetric('metric1', formData)).toBe(true);
|
||||
expect(isRegularMetric('metric2', formData)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for non-metrics', () => {
|
||||
const formData = createFormData(['metric1'], []);
|
||||
expect(isRegularMetric('non_metric', formData)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for percentage metrics', () => {
|
||||
const formData = createFormData([], ['percent_metric1']);
|
||||
expect(isRegularMetric('percent_metric1', formData)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isPercentMetric', () => {
|
||||
it('should return true for percentage metrics', () => {
|
||||
const formData = createFormData([], ['percent_metric1']);
|
||||
expect(isPercentMetric('%percent_metric1', formData)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for non-percentage metrics', () => {
|
||||
const formData = createFormData(['regular_metric'], []);
|
||||
expect(isPercentMetric('regular_metric', formData)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for regular metrics', () => {
|
||||
const formData = createFormData(['metric1'], []);
|
||||
expect(isPercentMetric('metric1', formData)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,95 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
QueryFormMetric,
|
||||
getMetricLabel,
|
||||
SqlaFormData,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
export interface MetricColumnFilterParams {
|
||||
colname: string;
|
||||
colnames: string[];
|
||||
formData: SqlaFormData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a column should be skipped based on metric filtering logic.
|
||||
*
|
||||
* This function implements the logic to skip unprefixed percent metric columns
|
||||
* if a prefixed version exists, but doesn't skip if it's also a regular metric.
|
||||
*
|
||||
* @param params - The parameters for metric column filtering
|
||||
* @returns true if the column should be skipped, false otherwise
|
||||
*/
|
||||
export function shouldSkipMetricColumn({
|
||||
colname,
|
||||
colnames,
|
||||
formData,
|
||||
}: MetricColumnFilterParams): boolean {
|
||||
if (!colname) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if this column name exists as a percent metric in form data
|
||||
const isPercentMetric = formData.percent_metrics?.some(
|
||||
(metric: QueryFormMetric) => getMetricLabel(metric) === colname,
|
||||
);
|
||||
|
||||
// Check if this column name exists as a regular metric in form data
|
||||
const isRegularMetric = formData.metrics?.some(
|
||||
(metric: QueryFormMetric) => getMetricLabel(metric) === colname,
|
||||
);
|
||||
|
||||
// Check if there's a prefixed version of this column in the column list
|
||||
const hasPrefixedVersion = colnames.includes(`%${colname}`);
|
||||
|
||||
// Skip if: has prefixed version AND is percent metric AND is NOT regular metric
|
||||
return hasPrefixedVersion && isPercentMetric && !isRegularMetric;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a column is a regular metric.
|
||||
*
|
||||
* @param colname - The column name to check
|
||||
* @param formData - The form data containing metrics
|
||||
* @returns true if the column is a regular metric, false otherwise
|
||||
*/
|
||||
export function isRegularMetric(
|
||||
colname: string,
|
||||
formData: SqlaFormData,
|
||||
): boolean {
|
||||
return !!formData.metrics?.some(metric => getMetricLabel(metric) === colname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a column is a percentage metric.
|
||||
*
|
||||
* @param colname: string,
|
||||
* @param formData - The form data containing percent_metrics
|
||||
* @returns true if the column is a percentage metric, false otherwise
|
||||
*/
|
||||
export function isPercentMetric(
|
||||
colname: string,
|
||||
formData: SqlaFormData,
|
||||
): boolean {
|
||||
return !!formData.percent_metrics?.some(
|
||||
(metric: QueryFormMetric) => `%${getMetricLabel(metric)}` === colname,
|
||||
);
|
||||
}
|
||||
@@ -65,20 +65,6 @@ test('should skip renameOperator if series does not exist', () => {
|
||||
).toEqual(undefined);
|
||||
});
|
||||
|
||||
test('should skip renameOperator if series does not exist and a single time shift exists', () => {
|
||||
expect(
|
||||
renameOperator(
|
||||
{ ...formData, ...{ time_compare: ['1 year ago'] } },
|
||||
{
|
||||
...queryObject,
|
||||
...{
|
||||
columns: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
).toEqual(undefined);
|
||||
});
|
||||
|
||||
test('should skip renameOperator if does not exist x_axis and is_timeseries', () => {
|
||||
expect(
|
||||
renameOperator(
|
||||
@@ -107,26 +93,6 @@ test('should add renameOperator', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('should add renameOperator if a metric exists and multiple time shift', () => {
|
||||
expect(
|
||||
renameOperator(
|
||||
{
|
||||
...formData,
|
||||
...{ time_compare: ['1 year ago', '2 years ago'] },
|
||||
},
|
||||
{
|
||||
...queryObject,
|
||||
...{
|
||||
columns: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
).toEqual({
|
||||
operation: 'rename',
|
||||
options: { columns: { 'count(*)': null }, inplace: true, level: 0 },
|
||||
});
|
||||
});
|
||||
|
||||
test('should add renameOperator if exists derived metrics', () => {
|
||||
[
|
||||
ComparisonType.Difference,
|
||||
@@ -210,6 +176,7 @@ test('should add renameOperator if exist "actual value" time comparison', () =>
|
||||
operation: 'rename',
|
||||
options: {
|
||||
columns: {
|
||||
'count(*)': null,
|
||||
'count(*)__1 year ago': '1 year ago',
|
||||
'count(*)__1 year later': '1 year later',
|
||||
},
|
||||
|
||||
@@ -25,13 +25,11 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
"@babel/runtime": "^7.28.2",
|
||||
"@babel/runtime": "^7.25.6",
|
||||
"@fontsource/fira-code": "^5.2.6",
|
||||
"@fontsource/inter": "^5.2.6",
|
||||
"@types/json-bigint": "^1.0.4",
|
||||
"ace-builds": "^1.43.1",
|
||||
"ag-grid-community": "^34.0.2",
|
||||
"ag-grid-react": "34.0.2",
|
||||
"brace": "^0.11.1",
|
||||
"classnames": "^2.2.5",
|
||||
"csstype": "^3.1.3",
|
||||
@@ -39,7 +37,7 @@
|
||||
"d3-format": "^1.3.2",
|
||||
"dayjs": "^1.11.13",
|
||||
"d3-interpolate": "^3.0.1",
|
||||
"d3-scale": "^4.0.2",
|
||||
"d3-scale": "^3.0.0",
|
||||
"d3-time": "^3.1.0",
|
||||
"d3-time-format": "^4.1.0",
|
||||
"dompurify": "^3.2.4",
|
||||
@@ -48,10 +46,10 @@
|
||||
"lodash": "^4.17.21",
|
||||
"math-expression-evaluator": "^2.0.6",
|
||||
"pretty-ms": "^9.2.0",
|
||||
"re-resizable": "^6.11.2",
|
||||
"re-resizable": "^6.10.1",
|
||||
"react-ace": "^10.1.0",
|
||||
"react-js-cron": "^5.2.0",
|
||||
"react-draggable": "^4.5.0",
|
||||
"react-draggable": "^4.4.6",
|
||||
"react-resize-detector": "^7.1.2",
|
||||
"react-syntax-highlighter": "^15.4.5",
|
||||
"react-ultimate-pagination": "^1.3.2",
|
||||
@@ -61,7 +59,7 @@
|
||||
"rehype-raw": "^7.0.0",
|
||||
"rehype-sanitize": "^6.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"reselect": "^5.1.1",
|
||||
"reselect": "^4.0.0",
|
||||
"rison": "^0.1.1",
|
||||
"seedrandom": "^3.0.5",
|
||||
"@visx/responsive": "^3.12.0",
|
||||
@@ -80,7 +78,7 @@
|
||||
"@types/lodash": "^4.17.20",
|
||||
"@types/math-expression-evaluator": "^1.3.3",
|
||||
"@types/node": "^22.10.3",
|
||||
"@types/prop-types": "^15.7.15",
|
||||
"@types/prop-types": "^15.7.2",
|
||||
"@types/rison": "0.1.0",
|
||||
"@types/seedrandom": "^3.0.8",
|
||||
"fetch-mock": "^11.1.4",
|
||||
|
||||
@@ -27,8 +27,8 @@ export default function FallbackComponent({ error, height, width }: Props) {
|
||||
return (
|
||||
<div
|
||||
css={(theme: SupersetTheme) => ({
|
||||
backgroundColor: theme.colorBgContainer,
|
||||
color: theme.colorText,
|
||||
backgroundColor: theme.colors.grayscale.dark2,
|
||||
color: theme.colors.grayscale.light5,
|
||||
overflow: 'auto',
|
||||
padding: 32,
|
||||
})}
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/** Type checking is disabled for this file due to reselect only supporting
|
||||
* TS declarations for selectors with up to 12 arguments. */
|
||||
// @ts-nocheck
|
||||
import { RefObject } from 'react';
|
||||
import { createSelector, lruMemoize } from 'reselect';
|
||||
import { createSelector } from 'reselect';
|
||||
import {
|
||||
AppSection,
|
||||
Behavior,
|
||||
@@ -34,7 +37,7 @@ import {
|
||||
SetDataMaskHook,
|
||||
} from '../types/Base';
|
||||
import { QueryData, DataRecordFilters } from '..';
|
||||
import { supersetTheme, SupersetTheme } from '../../theme';
|
||||
import { SupersetTheme } from '../../theme';
|
||||
|
||||
// TODO: more specific typing for these fields of ChartProps
|
||||
type AnnotationData = PlainObject;
|
||||
@@ -106,8 +109,6 @@ export interface ChartPropsConfig {
|
||||
theme: SupersetTheme;
|
||||
/* legend index */
|
||||
legendIndex?: number;
|
||||
inContextMenu?: boolean;
|
||||
emitCrossFilters?: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_WIDTH = 800;
|
||||
@@ -160,11 +161,7 @@ export default class ChartProps<FormData extends RawFormData = RawFormData> {
|
||||
|
||||
theme: SupersetTheme;
|
||||
|
||||
constructor(
|
||||
config: ChartPropsConfig & { formData?: FormData } = {
|
||||
theme: supersetTheme,
|
||||
},
|
||||
) {
|
||||
constructor(config: ChartPropsConfig & { formData?: FormData } = {}) {
|
||||
const {
|
||||
annotationData = {},
|
||||
datasource = {},
|
||||
@@ -279,16 +276,5 @@ ChartProps.createSelector = function create(): ChartPropsSelector {
|
||||
emitCrossFilters,
|
||||
theme,
|
||||
}),
|
||||
// Below config is to retain usage of 1-sized `lruMemoize` object in Reselect v4
|
||||
// Reselect v5 introduces `weakMapMemoize` which is more performant but potentially memory-leaky
|
||||
// due to infinite cache size.
|
||||
// Source: https://github.com/reduxjs/reselect/releases/tag/v5.0.1
|
||||
{
|
||||
memoize: lruMemoize,
|
||||
argsMemoize: lruMemoize,
|
||||
memoizeOptions: {
|
||||
maxSize: 10,
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
@@ -24,7 +24,6 @@ export const Badge = styled((props: BadgeProps) => <AntdBadge {...props} />)`
|
||||
${({ theme, color, count }) => `
|
||||
& > sup,
|
||||
& > sup.ant-badge-count {
|
||||
box-shadow: none;
|
||||
${
|
||||
count !== undefined ? `background: ${color || theme.colorPrimary};` : ''
|
||||
}
|
||||
|
||||
@@ -132,12 +132,11 @@ export function Button(props: ButtonProps) {
|
||||
'& > span > :first-of-type': {
|
||||
marginRight: firstChildMargin,
|
||||
},
|
||||
':not(:hover)': effectiveButtonStyle === 'secondary' &&
|
||||
!disabled && {
|
||||
// NOTE: This is the best we can do contrast wise for the secondary button using antd tokens
|
||||
// and abusing the semantics. Should be revisited when possible. https://github.com/apache/superset/pull/34253#issuecomment-3104834692
|
||||
color: `${theme.colorPrimaryTextHover} !important`,
|
||||
},
|
||||
':not(:hover)': effectiveButtonStyle === 'secondary' && {
|
||||
// NOTE: This is the best we can do contrast wise for the secondary button using antd tokens
|
||||
// and abusing the semantics. Should be revisited when possible. https://github.com/apache/superset/pull/34253#issuecomment-3104834692
|
||||
color: `${theme.colorPrimaryTextHover} !important`,
|
||||
},
|
||||
}}
|
||||
icon={icon}
|
||||
{...restProps}
|
||||
|
||||
@@ -52,7 +52,7 @@ export const CheckboxHalfChecked = () => {
|
||||
>
|
||||
<path
|
||||
d="M16 0H2C0.9 0 0 0.9 0 2V16C0 17.1 0.9 18 2 18H16C17.1 18 18 17.1 18 16V2C18 0.9 17.1 0 16 0Z"
|
||||
fill={theme.colorFill}
|
||||
fill={theme.colors.grayscale.light1}
|
||||
/>
|
||||
<path d="M14 10H4V8H14V10Z" fill="white" />
|
||||
</svg>
|
||||
@@ -71,7 +71,7 @@ export const CheckboxUnchecked = () => {
|
||||
>
|
||||
<path
|
||||
d="M16 0H2C0.9 0 0 0.9 0 2V16C0 17.1 0.9 18 2 18H16C17.1 18 18 17.1 18 16V2C18 0.9 17.1 0 16 0Z"
|
||||
fill={theme.colorFillSecondary}
|
||||
fill={theme.colors.grayscale.light2}
|
||||
/>
|
||||
<path d="M16 2V16H2V2H16V2Z" fill="white" />
|
||||
</svg>
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
ColorPicker as AntdColorPicker,
|
||||
type ColorPickerProps as AntdColorPickerProps,
|
||||
} from 'antd';
|
||||
|
||||
// Re-export the AntD ColorPicker as-is for themeable usage
|
||||
export type ColorPickerProps = AntdColorPickerProps;
|
||||
export const ColorPicker = AntdColorPicker;
|
||||
|
||||
// Export RGB color type for backward compatibility
|
||||
export type RGBColor = {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
a?: number;
|
||||
};
|
||||
|
||||
// Export type for AntD Color object interface
|
||||
export interface ColorValue {
|
||||
toRgb(): RGBColor;
|
||||
toHexString(): string;
|
||||
}
|
||||
|
||||
export default ColorPicker;
|
||||
@@ -27,7 +27,7 @@ const StyledDiv = styled.div`
|
||||
padding-top: 8px;
|
||||
width: 50%;
|
||||
label {
|
||||
color: ${({ theme }) => theme.colorTextLabel};
|
||||
color: ${({ theme }) => theme.colors.grayscale.base};
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { DrawerProps } from './types';
|
||||
|
||||
export { Drawer } from 'antd';
|
||||
export type { DrawerProps };
|
||||
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import type { DrawerProps } from 'antd/es/drawer';
|
||||
|
||||
export { DrawerProps };
|
||||
@@ -31,7 +31,7 @@ const MenuDots = styled.div`
|
||||
width: ${({ theme }) => theme.sizeUnit * 0.75}px;
|
||||
height: ${({ theme }) => theme.sizeUnit * 0.75}px;
|
||||
border-radius: 50%;
|
||||
background-color: ${({ theme }) => theme.colorFill};
|
||||
background-color: ${({ theme }) => theme.colors.grayscale.light1};
|
||||
|
||||
font-weight: ${({ theme }) => theme.fontWeightNormal};
|
||||
display: inline-flex;
|
||||
@@ -53,7 +53,7 @@ const MenuDots = styled.div`
|
||||
width: ${({ theme }) => theme.sizeUnit * 0.75}px;
|
||||
height: ${({ theme }) => theme.sizeUnit * 0.75}px;
|
||||
border-radius: 50%;
|
||||
background-color: ${({ theme }) => theme.colorFill};
|
||||
background-color: ${({ theme }) => theme.colors.grayscale.light1};
|
||||
}
|
||||
|
||||
&::before {
|
||||
|
||||
@@ -1,395 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
cloneElement,
|
||||
forwardRef,
|
||||
RefObject,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
useRef,
|
||||
useCallback,
|
||||
} from 'react';
|
||||
|
||||
import { Global } from '@emotion/react';
|
||||
import { css, t, useTheme, usePrevious } from '@superset-ui/core';
|
||||
import { useResizeDetector } from 'react-resize-detector';
|
||||
import { Badge, Icons, Button, Tooltip, Popover } from '..';
|
||||
import { DropdownContainerProps, DropdownItem, DropdownRef } from './types';
|
||||
|
||||
const MAX_HEIGHT = 500;
|
||||
|
||||
export const DropdownContainer = forwardRef(
|
||||
(
|
||||
{
|
||||
items,
|
||||
onOverflowingStateChange,
|
||||
dropdownContent,
|
||||
dropdownRef,
|
||||
dropdownStyle = {},
|
||||
dropdownTriggerCount,
|
||||
dropdownTriggerIcon,
|
||||
dropdownTriggerText = t('More'),
|
||||
dropdownTriggerTooltip = null,
|
||||
forceRender,
|
||||
style,
|
||||
}: DropdownContainerProps,
|
||||
outerRef: RefObject<DropdownRef>,
|
||||
) => {
|
||||
const theme = useTheme();
|
||||
const { ref, width = 0 } = useResizeDetector<HTMLDivElement>();
|
||||
const previousWidth = usePrevious(width) || 0;
|
||||
const { current } = ref;
|
||||
const [itemsWidth, setItemsWidth] = useState<number[]>([]);
|
||||
const [popoverVisible, setPopoverVisible] = useState(false);
|
||||
// We use React.useState to be able to mock the state in Jest
|
||||
const [overflowingIndex, setOverflowingIndex] = useState<number>(-1);
|
||||
|
||||
let targetRef = useRef<HTMLDivElement>(null);
|
||||
if (dropdownRef) {
|
||||
targetRef = dropdownRef;
|
||||
}
|
||||
|
||||
const [showOverflow, setShowOverflow] = useState(false);
|
||||
|
||||
// callback to update item widths so that the useLayoutEffect runs whenever
|
||||
// width of any of the child changes
|
||||
const recalculateItemWidths = useCallback(() => {
|
||||
const mainItemsContainerNode = current?.children.item(0);
|
||||
if (mainItemsContainerNode) {
|
||||
const visibleChildrenElements = Array.from(
|
||||
mainItemsContainerNode.children,
|
||||
);
|
||||
setItemsWidth(prevGlobalWidths => {
|
||||
if (prevGlobalWidths.length !== items.length) {
|
||||
return prevGlobalWidths;
|
||||
}
|
||||
|
||||
const newGlobalWidths = [...prevGlobalWidths];
|
||||
let changed = false;
|
||||
visibleChildrenElements.forEach((child, indexInVisible) => {
|
||||
const originalItemIndex = indexInVisible;
|
||||
if (originalItemIndex < newGlobalWidths.length) {
|
||||
const newWidth = child.getBoundingClientRect().width;
|
||||
if (newGlobalWidths[originalItemIndex] !== newWidth) {
|
||||
newGlobalWidths[originalItemIndex] = newWidth;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return changed ? newGlobalWidths : prevGlobalWidths;
|
||||
});
|
||||
}
|
||||
}, [current?.children, items.length]);
|
||||
|
||||
const reduceItems = (items: DropdownItem[]): [DropdownItem[], string[]] =>
|
||||
items.reduce(
|
||||
([items, ids], item) => {
|
||||
items.push({
|
||||
id: item.id,
|
||||
element: cloneElement(item.element, { key: item.id }),
|
||||
});
|
||||
ids.push(item.id);
|
||||
return [items, ids];
|
||||
},
|
||||
[[], []] as [DropdownItem[], string[]],
|
||||
);
|
||||
|
||||
const [notOverflowedItems, notOverflowedIds] = useMemo(
|
||||
() =>
|
||||
reduceItems(
|
||||
items.slice(
|
||||
0,
|
||||
overflowingIndex !== -1 ? overflowingIndex : items.length,
|
||||
),
|
||||
),
|
||||
[items, overflowingIndex],
|
||||
);
|
||||
|
||||
const [overflowedItems, overflowedIds] = useMemo(
|
||||
() =>
|
||||
overflowingIndex !== -1
|
||||
? reduceItems(items.slice(overflowingIndex))
|
||||
: [[], []],
|
||||
[items, overflowingIndex],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const container = current?.children.item(0);
|
||||
if (!container) return;
|
||||
|
||||
const childrenArray = Array.from(container.children);
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
recalculateItemWidths();
|
||||
});
|
||||
|
||||
childrenArray.map(child => resizeObserver.observe(child));
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
return () => {
|
||||
childrenArray.map(child => resizeObserver.unobserve(child));
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}, [items.length, current, recalculateItemWidths]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (popoverVisible) {
|
||||
return;
|
||||
}
|
||||
const container = current?.children.item(0);
|
||||
if (container) {
|
||||
const { children } = container;
|
||||
const childrenArray = Array.from(children);
|
||||
// If items length change, add all items to the container
|
||||
// and recalculate the widths
|
||||
if (itemsWidth.length !== items.length) {
|
||||
if (childrenArray.length === items.length) {
|
||||
setItemsWidth(
|
||||
childrenArray.map(child => child.getBoundingClientRect().width),
|
||||
);
|
||||
} else {
|
||||
setOverflowingIndex(-1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates the index of the first overflowed element
|
||||
// +1 is to give at least one pixel of difference and avoid flakiness
|
||||
const index = childrenArray.findIndex(
|
||||
child =>
|
||||
child.getBoundingClientRect().right >
|
||||
container.getBoundingClientRect().right + 1,
|
||||
);
|
||||
|
||||
// If elements fit (-1) and there's overflowed items
|
||||
// then preserve the overflow index. We can't use overflowIndex
|
||||
// directly because the items may have been modified
|
||||
let newOverflowingIndex =
|
||||
index === -1 && overflowedItems.length > 0
|
||||
? items.length - overflowedItems.length
|
||||
: index;
|
||||
|
||||
if (width > previousWidth) {
|
||||
// Calculates remaining space in the container
|
||||
const button = current?.children.item(1);
|
||||
const buttonRight = button?.getBoundingClientRect().right || 0;
|
||||
const containerRight = current?.getBoundingClientRect().right || 0;
|
||||
const remainingSpace = containerRight - buttonRight;
|
||||
|
||||
// Checks if some elements in the dropdown fits in the remaining space
|
||||
let sum = 0;
|
||||
for (let i = childrenArray.length; i < items.length; i += 1) {
|
||||
sum += itemsWidth[i];
|
||||
if (sum <= remainingSpace) {
|
||||
newOverflowingIndex = i + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setOverflowingIndex(newOverflowingIndex);
|
||||
}
|
||||
}, [
|
||||
current,
|
||||
items.length,
|
||||
itemsWidth,
|
||||
overflowedItems.length,
|
||||
previousWidth,
|
||||
width,
|
||||
popoverVisible,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (onOverflowingStateChange) {
|
||||
onOverflowingStateChange({
|
||||
notOverflowed: notOverflowedIds,
|
||||
overflowed: overflowedIds,
|
||||
});
|
||||
}
|
||||
}, [notOverflowedIds, onOverflowingStateChange, overflowedIds]);
|
||||
|
||||
const overflowingCount =
|
||||
overflowingIndex !== -1 ? items.length - overflowingIndex : 0;
|
||||
|
||||
const popoverContent = useMemo(
|
||||
() =>
|
||||
dropdownContent || overflowingCount ? (
|
||||
<div
|
||||
css={css`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${theme.sizeUnit * 4}px;
|
||||
`}
|
||||
data-test="dropdown-content"
|
||||
style={dropdownStyle}
|
||||
ref={targetRef}
|
||||
>
|
||||
{dropdownContent
|
||||
? dropdownContent(overflowedItems)
|
||||
: overflowedItems.map(item => item.element)}
|
||||
</div>
|
||||
) : null,
|
||||
[
|
||||
dropdownContent,
|
||||
overflowingCount,
|
||||
theme.sizeUnit,
|
||||
dropdownStyle,
|
||||
overflowedItems,
|
||||
],
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (popoverVisible) {
|
||||
// Measures scroll height after rendering the elements
|
||||
setTimeout(() => {
|
||||
if (targetRef.current) {
|
||||
// We only set overflow when there's enough space to display
|
||||
// Select's popovers because they are restrained by the overflow property.
|
||||
setShowOverflow(targetRef.current.scrollHeight > MAX_HEIGHT);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}, [popoverVisible]);
|
||||
|
||||
useImperativeHandle(
|
||||
outerRef,
|
||||
() => ({
|
||||
...(ref.current as HTMLDivElement),
|
||||
open: () => setPopoverVisible(true),
|
||||
}),
|
||||
[ref],
|
||||
);
|
||||
|
||||
// Closes the popover when scrolling on the document
|
||||
useEffect(() => {
|
||||
document.onscroll = popoverVisible
|
||||
? () => setPopoverVisible(false)
|
||||
: null;
|
||||
return () => {
|
||||
document.onscroll = null;
|
||||
};
|
||||
}, [popoverVisible]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
css={css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`}
|
||||
>
|
||||
<div
|
||||
css={css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: ${theme.sizeUnit * 4}px;
|
||||
margin-right: ${theme.sizeUnit * 4}px;
|
||||
min-width: 0px;
|
||||
`}
|
||||
data-test="container"
|
||||
style={style}
|
||||
>
|
||||
{notOverflowedItems.map(item => item.element)}
|
||||
</div>
|
||||
{popoverContent && (
|
||||
<>
|
||||
<Global
|
||||
styles={css`
|
||||
.ant-popover-inner {
|
||||
// Some OS versions only show the scroll when hovering.
|
||||
// These settings will make the scroll always visible.
|
||||
::-webkit-scrollbar {
|
||||
-webkit-appearance: none;
|
||||
width: 14px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 9px;
|
||||
background-color: ${theme.colorFillSecondary};
|
||||
border: 3px solid transparent;
|
||||
background-clip: content-box;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: ${theme.colorFillQuaternary};
|
||||
border-left: 1px solid ${theme.colorFillTertiary};
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
|
||||
<Popover
|
||||
styles={{
|
||||
body: {
|
||||
maxHeight: `${MAX_HEIGHT}px`,
|
||||
overflow: showOverflow ? 'auto' : 'visible',
|
||||
},
|
||||
}}
|
||||
content={popoverContent}
|
||||
trigger="click"
|
||||
open={popoverVisible}
|
||||
onOpenChange={visible => setPopoverVisible(visible)}
|
||||
placement="bottom"
|
||||
forceRender={forceRender}
|
||||
>
|
||||
<Tooltip title={dropdownTriggerTooltip}>
|
||||
<Button
|
||||
buttonStyle="secondary"
|
||||
data-test="dropdown-container-btn"
|
||||
icon={dropdownTriggerIcon}
|
||||
css={css`
|
||||
padding-left: ${theme.paddingXS}px;
|
||||
padding-right: ${theme.paddingXXS}px;
|
||||
gap: ${theme.sizeXXS}px;
|
||||
`}
|
||||
>
|
||||
{dropdownTriggerText}
|
||||
<Badge
|
||||
count={dropdownTriggerCount ?? overflowingCount}
|
||||
color={
|
||||
(dropdownTriggerCount ?? overflowingCount) > 0
|
||||
? theme.colorPrimary
|
||||
: theme.colorTextSecondary
|
||||
}
|
||||
showZero
|
||||
css={css`
|
||||
margin-left: ${theme.sizeUnit * 2}px;
|
||||
`}
|
||||
/>
|
||||
<Icons.DownOutlined
|
||||
iconSize="m"
|
||||
iconColor={theme.colorIcon}
|
||||
css={css`
|
||||
.anticon {
|
||||
display: flex;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Popover>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -16,6 +16,448 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
CSSProperties,
|
||||
cloneElement,
|
||||
forwardRef,
|
||||
ReactElement,
|
||||
RefObject,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
useRef,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
} from 'react';
|
||||
|
||||
export { DropdownContainer } from './DropdownContainer';
|
||||
export type * from './types';
|
||||
import { Global } from '@emotion/react';
|
||||
import { css, t, useTheme, usePrevious } from '@superset-ui/core';
|
||||
import { useResizeDetector } from 'react-resize-detector';
|
||||
import { Badge, Icons, Button, Tooltip, Popover } from '..';
|
||||
/**
|
||||
* Container item.
|
||||
*/
|
||||
export interface DropdownItem {
|
||||
/**
|
||||
* String that uniquely identifies the item.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The element to be rendered.
|
||||
*/
|
||||
element: ReactElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Horizontal container that displays overflowed items in a dropdown.
|
||||
* It shows an indicator of how many items are currently overflowing.
|
||||
*/
|
||||
export interface DropdownContainerProps {
|
||||
/**
|
||||
* Array of items. The id property is used to uniquely identify
|
||||
* the elements when rendering or dealing with event handlers.
|
||||
*/
|
||||
items: DropdownItem[];
|
||||
/**
|
||||
* Event handler called every time an element moves between
|
||||
* main container and dropdown.
|
||||
*/
|
||||
onOverflowingStateChange?: (overflowingState: {
|
||||
notOverflowed: string[];
|
||||
overflowed: string[];
|
||||
}) => void;
|
||||
/**
|
||||
* Option to customize the content of the dropdown.
|
||||
*/
|
||||
dropdownContent?: (overflowedItems: DropdownItem[]) => ReactElement;
|
||||
/**
|
||||
* Dropdown ref.
|
||||
*/
|
||||
dropdownRef?: RefObject<HTMLDivElement>;
|
||||
/**
|
||||
* Dropdown additional style properties.
|
||||
*/
|
||||
dropdownStyle?: CSSProperties;
|
||||
/**
|
||||
* Displayed count in the dropdown trigger.
|
||||
*/
|
||||
dropdownTriggerCount?: number;
|
||||
/**
|
||||
* Icon of the dropdown trigger.
|
||||
*/
|
||||
dropdownTriggerIcon?: ReactElement;
|
||||
/**
|
||||
* Text of the dropdown trigger.
|
||||
*/
|
||||
dropdownTriggerText?: string;
|
||||
/**
|
||||
* Text of the dropdown trigger tooltip
|
||||
*/
|
||||
dropdownTriggerTooltip?: ReactNode | null;
|
||||
/**
|
||||
* Main container additional style properties.
|
||||
*/
|
||||
style?: CSSProperties;
|
||||
/**
|
||||
* Force render popover content before it's first opened
|
||||
*/
|
||||
forceRender?: boolean;
|
||||
}
|
||||
|
||||
export type DropdownRef = HTMLDivElement & { open: () => void };
|
||||
|
||||
const MAX_HEIGHT = 500;
|
||||
|
||||
export const DropdownContainer = forwardRef(
|
||||
(
|
||||
{
|
||||
items,
|
||||
onOverflowingStateChange,
|
||||
dropdownContent,
|
||||
dropdownRef,
|
||||
dropdownStyle = {},
|
||||
dropdownTriggerCount,
|
||||
dropdownTriggerIcon,
|
||||
dropdownTriggerText = t('More'),
|
||||
dropdownTriggerTooltip = null,
|
||||
forceRender,
|
||||
style,
|
||||
}: DropdownContainerProps,
|
||||
outerRef: RefObject<DropdownRef>,
|
||||
) => {
|
||||
const theme = useTheme();
|
||||
const { ref, width = 0 } = useResizeDetector<HTMLDivElement>();
|
||||
const previousWidth = usePrevious(width) || 0;
|
||||
const { current } = ref;
|
||||
const [itemsWidth, setItemsWidth] = useState<number[]>([]);
|
||||
const [popoverVisible, setPopoverVisible] = useState(false);
|
||||
// We use React.useState to be able to mock the state in Jest
|
||||
const [overflowingIndex, setOverflowingIndex] = useState<number>(-1);
|
||||
|
||||
let targetRef = useRef<HTMLDivElement>(null);
|
||||
if (dropdownRef) {
|
||||
targetRef = dropdownRef;
|
||||
}
|
||||
|
||||
const [showOverflow, setShowOverflow] = useState(false);
|
||||
|
||||
// callback to update item widths so that the useLayoutEffect runs whenever
|
||||
// width of any of the child changes
|
||||
const recalculateItemWidths = useCallback(() => {
|
||||
const mainItemsContainerNode = current?.children.item(0);
|
||||
if (mainItemsContainerNode) {
|
||||
const visibleChildrenElements = Array.from(
|
||||
mainItemsContainerNode.children,
|
||||
);
|
||||
setItemsWidth(prevGlobalWidths => {
|
||||
if (prevGlobalWidths.length !== items.length) {
|
||||
return prevGlobalWidths;
|
||||
}
|
||||
|
||||
const newGlobalWidths = [...prevGlobalWidths];
|
||||
let changed = false;
|
||||
visibleChildrenElements.forEach((child, indexInVisible) => {
|
||||
const originalItemIndex = indexInVisible;
|
||||
if (originalItemIndex < newGlobalWidths.length) {
|
||||
const newWidth = child.getBoundingClientRect().width;
|
||||
if (newGlobalWidths[originalItemIndex] !== newWidth) {
|
||||
newGlobalWidths[originalItemIndex] = newWidth;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return changed ? newGlobalWidths : prevGlobalWidths;
|
||||
});
|
||||
}
|
||||
}, [current?.children, items.length]);
|
||||
|
||||
const reduceItems = (items: DropdownItem[]): [DropdownItem[], string[]] =>
|
||||
items.reduce(
|
||||
([items, ids], item) => {
|
||||
items.push({
|
||||
id: item.id,
|
||||
element: cloneElement(item.element, { key: item.id }),
|
||||
});
|
||||
ids.push(item.id);
|
||||
return [items, ids];
|
||||
},
|
||||
[[], []] as [DropdownItem[], string[]],
|
||||
);
|
||||
|
||||
const [notOverflowedItems, notOverflowedIds] = useMemo(
|
||||
() =>
|
||||
reduceItems(
|
||||
items.slice(
|
||||
0,
|
||||
overflowingIndex !== -1 ? overflowingIndex : items.length,
|
||||
),
|
||||
),
|
||||
[items, overflowingIndex],
|
||||
);
|
||||
|
||||
const [overflowedItems, overflowedIds] = useMemo(
|
||||
() =>
|
||||
overflowingIndex !== -1
|
||||
? reduceItems(items.slice(overflowingIndex))
|
||||
: [[], []],
|
||||
[items, overflowingIndex],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const container = current?.children.item(0);
|
||||
if (!container) return;
|
||||
|
||||
const childrenArray = Array.from(container.children);
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
recalculateItemWidths();
|
||||
});
|
||||
|
||||
childrenArray.map(child => resizeObserver.observe(child));
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
return () => {
|
||||
childrenArray.map(child => resizeObserver.unobserve(child));
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}, [items.length, current, recalculateItemWidths]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (popoverVisible) {
|
||||
return;
|
||||
}
|
||||
const container = current?.children.item(0);
|
||||
if (container) {
|
||||
const { children } = container;
|
||||
const childrenArray = Array.from(children);
|
||||
// If items length change, add all items to the container
|
||||
// and recalculate the widths
|
||||
if (itemsWidth.length !== items.length) {
|
||||
if (childrenArray.length === items.length) {
|
||||
setItemsWidth(
|
||||
childrenArray.map(child => child.getBoundingClientRect().width),
|
||||
);
|
||||
} else {
|
||||
setOverflowingIndex(-1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates the index of the first overflowed element
|
||||
// +1 is to give at least one pixel of difference and avoid flakiness
|
||||
const index = childrenArray.findIndex(
|
||||
child =>
|
||||
child.getBoundingClientRect().right >
|
||||
container.getBoundingClientRect().right + 1,
|
||||
);
|
||||
|
||||
// If elements fit (-1) and there's overflowed items
|
||||
// then preserve the overflow index. We can't use overflowIndex
|
||||
// directly because the items may have been modified
|
||||
let newOverflowingIndex =
|
||||
index === -1 && overflowedItems.length > 0
|
||||
? items.length - overflowedItems.length
|
||||
: index;
|
||||
|
||||
if (width > previousWidth) {
|
||||
// Calculates remaining space in the container
|
||||
const button = current?.children.item(1);
|
||||
const buttonRight = button?.getBoundingClientRect().right || 0;
|
||||
const containerRight = current?.getBoundingClientRect().right || 0;
|
||||
const remainingSpace = containerRight - buttonRight;
|
||||
|
||||
// Checks if some elements in the dropdown fits in the remaining space
|
||||
let sum = 0;
|
||||
for (let i = childrenArray.length; i < items.length; i += 1) {
|
||||
sum += itemsWidth[i];
|
||||
if (sum <= remainingSpace) {
|
||||
newOverflowingIndex = i + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setOverflowingIndex(newOverflowingIndex);
|
||||
}
|
||||
}, [
|
||||
current,
|
||||
items.length,
|
||||
itemsWidth,
|
||||
overflowedItems.length,
|
||||
previousWidth,
|
||||
width,
|
||||
popoverVisible,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (onOverflowingStateChange) {
|
||||
onOverflowingStateChange({
|
||||
notOverflowed: notOverflowedIds,
|
||||
overflowed: overflowedIds,
|
||||
});
|
||||
}
|
||||
}, [notOverflowedIds, onOverflowingStateChange, overflowedIds]);
|
||||
|
||||
const overflowingCount =
|
||||
overflowingIndex !== -1 ? items.length - overflowingIndex : 0;
|
||||
|
||||
const popoverContent = useMemo(
|
||||
() =>
|
||||
dropdownContent || overflowingCount ? (
|
||||
<div
|
||||
css={css`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${theme.sizeUnit * 4}px;
|
||||
`}
|
||||
data-test="dropdown-content"
|
||||
style={dropdownStyle}
|
||||
ref={targetRef}
|
||||
>
|
||||
{dropdownContent
|
||||
? dropdownContent(overflowedItems)
|
||||
: overflowedItems.map(item => item.element)}
|
||||
</div>
|
||||
) : null,
|
||||
[
|
||||
dropdownContent,
|
||||
overflowingCount,
|
||||
theme.sizeUnit,
|
||||
dropdownStyle,
|
||||
overflowedItems,
|
||||
],
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (popoverVisible) {
|
||||
// Measures scroll height after rendering the elements
|
||||
setTimeout(() => {
|
||||
if (targetRef.current) {
|
||||
// We only set overflow when there's enough space to display
|
||||
// Select's popovers because they are restrained by the overflow property.
|
||||
setShowOverflow(targetRef.current.scrollHeight > MAX_HEIGHT);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}, [popoverVisible]);
|
||||
|
||||
useImperativeHandle(
|
||||
outerRef,
|
||||
() => ({
|
||||
...(ref.current as HTMLDivElement),
|
||||
open: () => setPopoverVisible(true),
|
||||
}),
|
||||
[ref],
|
||||
);
|
||||
|
||||
// Closes the popover when scrolling on the document
|
||||
useEffect(() => {
|
||||
document.onscroll = popoverVisible
|
||||
? () => setPopoverVisible(false)
|
||||
: null;
|
||||
return () => {
|
||||
document.onscroll = null;
|
||||
};
|
||||
}, [popoverVisible]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
css={css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`}
|
||||
>
|
||||
<div
|
||||
css={css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: ${theme.sizeUnit * 4}px;
|
||||
margin-right: ${theme.sizeUnit * 4}px;
|
||||
min-width: 0px;
|
||||
`}
|
||||
data-test="container"
|
||||
style={style}
|
||||
>
|
||||
{notOverflowedItems.map(item => item.element)}
|
||||
</div>
|
||||
{popoverContent && (
|
||||
<>
|
||||
<Global
|
||||
styles={css`
|
||||
.ant-popover-inner {
|
||||
// Some OS versions only show the scroll when hovering.
|
||||
// These settings will make the scroll always visible.
|
||||
::-webkit-scrollbar {
|
||||
-webkit-appearance: none;
|
||||
width: 14px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 9px;
|
||||
background-color: ${theme.colors.grayscale.light1};
|
||||
border: 3px solid transparent;
|
||||
background-clip: content-box;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: ${theme.colors.grayscale.light4};
|
||||
border-left: 1px solid ${theme.colors.grayscale.light2};
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
|
||||
<Popover
|
||||
styles={{
|
||||
body: {
|
||||
maxHeight: `${MAX_HEIGHT}px`,
|
||||
overflow: showOverflow ? 'auto' : 'visible',
|
||||
},
|
||||
}}
|
||||
content={popoverContent}
|
||||
trigger="click"
|
||||
open={popoverVisible}
|
||||
onOpenChange={visible => setPopoverVisible(visible)}
|
||||
placement="bottom"
|
||||
forceRender={forceRender}
|
||||
>
|
||||
<Tooltip title={dropdownTriggerTooltip}>
|
||||
<Button
|
||||
buttonStyle="secondary"
|
||||
data-test="dropdown-container-btn"
|
||||
>
|
||||
{dropdownTriggerIcon}
|
||||
{dropdownTriggerText}
|
||||
<Badge
|
||||
count={dropdownTriggerCount ?? overflowingCount}
|
||||
color={
|
||||
(dropdownTriggerCount ?? overflowingCount) > 0
|
||||
? theme.colorPrimary
|
||||
: theme.colors.grayscale.light1
|
||||
}
|
||||
showZero
|
||||
css={css`
|
||||
margin-left: ${theme.sizeUnit * 2}px;
|
||||
`}
|
||||
/>
|
||||
<Icons.DownOutlined
|
||||
iconSize="m"
|
||||
iconColor={theme.colors.grayscale.light1}
|
||||
css={css`
|
||||
.anticon {
|
||||
display: flex;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Popover>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
* under the License.
|
||||
*/
|
||||
import type { CSSProperties, ReactElement, RefObject, ReactNode } from 'react';
|
||||
import { IconType } from '../Icons';
|
||||
|
||||
/**
|
||||
* Container item.
|
||||
@@ -70,7 +69,7 @@ export interface DropdownContainerProps {
|
||||
/**
|
||||
* Icon of the dropdown trigger.
|
||||
*/
|
||||
dropdownTriggerIcon?: IconType;
|
||||
dropdownTriggerIcon?: ReactElement;
|
||||
/**
|
||||
* Text of the dropdown trigger.
|
||||
*/
|
||||
|
||||
@@ -28,17 +28,14 @@ export default {
|
||||
component: BaseIconComponent,
|
||||
};
|
||||
|
||||
const palette: Record<string, string | null> = {
|
||||
Default: null,
|
||||
Primary: supersetTheme.colorPrimary,
|
||||
Success: supersetTheme.colorSuccess,
|
||||
Warning: supersetTheme.colorWarning,
|
||||
Error: supersetTheme.colorError,
|
||||
Info: supersetTheme.colorInfo,
|
||||
Text: supersetTheme.colorText,
|
||||
'Text Secondary': supersetTheme.colorTextSecondary,
|
||||
Icon: supersetTheme.colorIcon,
|
||||
};
|
||||
const palette: Record<string, string | null> = { Default: null };
|
||||
Object.entries(supersetTheme.colors).forEach(([familyName, family]) => {
|
||||
Object.entries(family as Record<string, string>).forEach(
|
||||
([colorName, colorValue]) => {
|
||||
palette[`${familyName} / ${colorName}`] = colorValue;
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
const IconSet = styled.div`
|
||||
display: grid;
|
||||
|
||||
@@ -25,7 +25,7 @@ import type { LabelProps } from './types';
|
||||
|
||||
export function Label(props: LabelProps) {
|
||||
const theme = useTheme();
|
||||
// Use Ant Design's motion duration instead of deprecated transitionTiming
|
||||
const { transitionTiming } = theme;
|
||||
const {
|
||||
type = 'default',
|
||||
monospace = false,
|
||||
@@ -46,7 +46,7 @@ export function Label(props: LabelProps) {
|
||||
const borderColorHover = onClick ? baseColor.borderHover : borderColor;
|
||||
|
||||
const labelStyles = css`
|
||||
transition: background-color ${theme.motionDurationMid};
|
||||
transition: background-color ${transitionTiming}s;
|
||||
white-space: nowrap;
|
||||
cursor: ${onClick ? 'pointer' : 'default'};
|
||||
overflow: hidden;
|
||||
|
||||
@@ -45,16 +45,7 @@ export const DatasetTypeLabel: React.FC<DatasetTypeLabelProps> = ({
|
||||
const labelType = datasetType === 'physical' ? 'primary' : 'default';
|
||||
|
||||
return (
|
||||
<Label
|
||||
icon={icon}
|
||||
type={labelType}
|
||||
style={{
|
||||
color:
|
||||
datasetType === 'physical'
|
||||
? theme.colorPrimaryText
|
||||
: theme.colorPrimary,
|
||||
}}
|
||||
>
|
||||
<Label icon={icon} type={labelType}>
|
||||
{label}
|
||||
</Label>
|
||||
);
|
||||
|
||||
@@ -53,7 +53,7 @@ const StyledCard = styled(Card)`
|
||||
|
||||
const Cover = styled.div`
|
||||
height: 264px;
|
||||
border-bottom: 1px solid ${({ theme }) => theme.colorSplit};
|
||||
border-bottom: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
|
||||
overflow: hidden;
|
||||
|
||||
.cover-footer {
|
||||
|
||||
@@ -53,7 +53,7 @@ const StyledMenuItem = styled(AntdMenu.Item)`
|
||||
justify-content: space-between;
|
||||
}
|
||||
a {
|
||||
transition: background-color ${theme.motionDurationMid};
|
||||
transition: background-color ${theme.motionDurationMid}s;
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
@@ -63,7 +63,7 @@ const StyledMenuItem = styled(AntdMenu.Item)`
|
||||
height: 3px;
|
||||
opacity: 0;
|
||||
transform: translateX(-50%);
|
||||
transition: translate ${theme.motionDurationMid};
|
||||
transition: translate ${theme.motionDurationMid}s;
|
||||
}
|
||||
&:focus {
|
||||
@media (max-width: 767px) {
|
||||
@@ -140,7 +140,7 @@ const StyledSubMenu = styled(AntdMenu.SubMenu)`
|
||||
height: 3px;
|
||||
opacity: 0;
|
||||
transform: translateX(-50%);
|
||||
transition: all ${theme.motionDurationMid};
|
||||
transition: all ${theme.transitionTiming}s;
|
||||
}
|
||||
}
|
||||
`}
|
||||
|
||||
@@ -30,7 +30,7 @@ const MetadataWrapper = styled.div`
|
||||
|
||||
const MetadataText = styled.span`
|
||||
font-size: ${({ theme }) => theme.fontSizeXS}px;
|
||||
color: ${({ theme }) => theme.colorTextSecondary};
|
||||
color: ${({ theme }) => theme.colors.grayscale.light1};
|
||||
font-weight: ${({ theme }) => theme.fontWeightStrong};
|
||||
`;
|
||||
|
||||
|
||||
@@ -60,12 +60,12 @@ const menuItemStyles = (theme: any) => css`
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: ${theme.colorFillQuaternary};
|
||||
background: ${theme.colors.grayscale.light3};
|
||||
}
|
||||
|
||||
&.active {
|
||||
font-weight: ${theme.fontWeightStrong};
|
||||
background: ${theme.colorFillTertiary};
|
||||
background: ${theme.colors.grayscale.light2};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,14 +66,16 @@ export default function PopoverSection({
|
||||
<Icons.InfoCircleOutlined
|
||||
role="img"
|
||||
iconSize="s"
|
||||
iconColor={theme.colorIcon}
|
||||
iconColor={theme.colors.grayscale.light1}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Icons.CheckOutlined
|
||||
iconSize="s"
|
||||
role="img"
|
||||
iconColor={isSelected ? theme.colorPrimary : theme.colorIcon}
|
||||
iconColor={
|
||||
isSelected ? theme.colorPrimary : theme.colors.grayscale.base
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -45,7 +45,7 @@ const RefreshLabel = ({
|
||||
onClick={disabled ? undefined : onClick}
|
||||
css={(theme: SupersetTheme) => ({
|
||||
cursor: 'pointer',
|
||||
color: theme.colorIcon,
|
||||
color: theme.colors.grayscale.base,
|
||||
'&:hover': { color: theme.colorPrimary },
|
||||
})}
|
||||
/>
|
||||
|
||||
@@ -1047,119 +1047,6 @@ test('typing and deleting the last character for a new option displays correctly
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
describe('grouped options search', () => {
|
||||
const GROUPED_OPTIONS = [
|
||||
{
|
||||
label: 'Male',
|
||||
options: OPTIONS.filter(option => option.gender === 'Male'),
|
||||
},
|
||||
{
|
||||
label: 'Female',
|
||||
options: OPTIONS.filter(option => option.gender === 'Female'),
|
||||
},
|
||||
];
|
||||
|
||||
it('searches within grouped options and shows matching groups', async () => {
|
||||
render(<Select {...defaultProps} options={GROUPED_OPTIONS} />);
|
||||
await open();
|
||||
|
||||
await type('John');
|
||||
|
||||
expect(await findSelectOption('John')).toBeInTheDocument();
|
||||
expect(await findSelectOption('Johnny')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Female')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Olivia')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('Male')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Female')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows multiple groups when search matches both', async () => {
|
||||
render(<Select {...defaultProps} options={GROUPED_OPTIONS} />);
|
||||
await open();
|
||||
|
||||
await type('er');
|
||||
|
||||
expect(screen.getByText('Male')).toBeInTheDocument();
|
||||
expect(screen.getByText('Female')).toBeInTheDocument();
|
||||
expect(await findSelectOption('Oliver')).toBeInTheDocument();
|
||||
expect(await findSelectOption('Cher')).toBeInTheDocument();
|
||||
expect(await findSelectOption('Her')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('handles case-insensitive search in grouped options', async () => {
|
||||
render(<Select {...defaultProps} options={GROUPED_OPTIONS} />);
|
||||
await open();
|
||||
|
||||
await type('EMMA');
|
||||
|
||||
expect(await findSelectOption('Emma')).toBeInTheDocument();
|
||||
expect(screen.getByText('Female')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Male')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows no options when search matches nothing in any group', async () => {
|
||||
render(<Select {...defaultProps} options={GROUPED_OPTIONS} />);
|
||||
await open();
|
||||
|
||||
await type('xyz123');
|
||||
|
||||
expect(screen.queryByText('Male')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Female')).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(NO_DATA, { selector: '.ant-empty-description' }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('works in multiple selection mode with grouped options', async () => {
|
||||
render(
|
||||
<Select {...defaultProps} options={GROUPED_OPTIONS} mode="multiple" />,
|
||||
);
|
||||
await open();
|
||||
|
||||
await type('John');
|
||||
|
||||
await userEvent.click(await findSelectOption('John'));
|
||||
|
||||
// Clear search and search for female name
|
||||
await clearTypedText();
|
||||
await type('Emma');
|
||||
await userEvent.click(await findSelectOption('Emma'));
|
||||
|
||||
// Both should be selected
|
||||
const values = await findAllSelectValues();
|
||||
expect(values).toHaveLength(2);
|
||||
expect(values[0]).toHaveTextContent('John');
|
||||
expect(values[1]).toHaveTextContent('Emma');
|
||||
});
|
||||
|
||||
it('preserves group structure when not searching', async () => {
|
||||
render(<Select {...defaultProps} options={GROUPED_OPTIONS} />);
|
||||
await open();
|
||||
|
||||
expect(screen.getByText('Male')).toBeInTheDocument();
|
||||
expect(screen.getByText('Female')).toBeInTheDocument();
|
||||
expect(await findSelectOption('John')).toBeInTheDocument();
|
||||
expect(await findSelectOption('Emma')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('handles empty groups gracefully', async () => {
|
||||
const optionsWithEmptyGroup = [
|
||||
...GROUPED_OPTIONS,
|
||||
{
|
||||
label: 'Empty Group',
|
||||
options: [],
|
||||
},
|
||||
];
|
||||
|
||||
render(<Select {...defaultProps} options={optionsWithEmptyGroup} />);
|
||||
await open();
|
||||
|
||||
await type('John');
|
||||
expect(await findSelectOption('John')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Empty Group')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
TODO: Add tests that require scroll interaction. Needs further investigation.
|
||||
- Fetches more data when scrolling and more data is available
|
||||
|
||||
@@ -373,27 +373,9 @@ const Select = forwardRef(
|
||||
setSelectOptions(updatedOptions);
|
||||
}
|
||||
|
||||
const filteredOptions = updatedOptions
|
||||
.map((option: any) => {
|
||||
/*
|
||||
If it's a group, filter its nested options and only return it
|
||||
if it has matching options
|
||||
*/
|
||||
if ('options' in option && Array.isArray(option.options)) {
|
||||
const filteredGroupOptions = option.options.filter(
|
||||
(subOption: AntdLabeledValue) =>
|
||||
handleFilterOption(search, subOption),
|
||||
);
|
||||
return filteredGroupOptions.length > 0
|
||||
? { ...option, options: filteredGroupOptions }
|
||||
: null;
|
||||
}
|
||||
|
||||
return handleFilterOption(search, option as AntdLabeledValue)
|
||||
? option
|
||||
: null;
|
||||
})
|
||||
.filter((option): option is AntdLabeledValue => option !== null);
|
||||
const filteredOptions = updatedOptions.filter(
|
||||
(option: AntdLabeledValue) => handleFilterOption(search, option),
|
||||
);
|
||||
|
||||
setVisibleOptions(filteredOptions);
|
||||
setInputValue(searchValue);
|
||||
|
||||
@@ -32,9 +32,8 @@ export const StyledHeader = styled.span<{ headerPosition: string }>`
|
||||
`;
|
||||
|
||||
export const StyledContainer = styled.div<{ headerPosition: string }>`
|
||||
${({ headerPosition, theme }) => `
|
||||
${({ headerPosition }) => `
|
||||
display: flex;
|
||||
gap: ${theme.sizeUnit}px;
|
||||
flex-direction: ${headerPosition === 'top' ? 'column' : 'row'};
|
||||
align-items: ${headerPosition === 'left' ? 'center' : undefined};
|
||||
width: 100%;
|
||||
@@ -104,17 +103,17 @@ export const StyledLoadingText = styled.div`
|
||||
${({ theme }) => `
|
||||
margin-left: ${theme.sizeUnit * 3}px;
|
||||
line-height: ${theme.sizeUnit * 8}px;
|
||||
color: ${theme.colorTextSecondary};
|
||||
color: ${theme.colors.grayscale.light1};
|
||||
`}
|
||||
`;
|
||||
|
||||
export const StyledHelperText = styled.div`
|
||||
${({ theme }) => `
|
||||
padding: ${theme.sizeUnit * 2}px ${theme.sizeUnit * 3}px;
|
||||
color: ${theme.colorText};
|
||||
color: ${theme.colors.grayscale.base};
|
||||
font-size: ${theme.fontSizeSM}px;
|
||||
cursor: default;
|
||||
border-bottom: 1px solid ${theme.colorBorderSecondary};
|
||||
border-bottom: 1px solid ${theme.colors.grayscale.light2};
|
||||
`}
|
||||
`;
|
||||
|
||||
@@ -140,6 +139,6 @@ export const StyledErrorMessage = styled.div`
|
||||
export const StyledBulkActionsContainer = styled(Flex)`
|
||||
${({ theme }) => `
|
||||
padding: ${theme.sizeUnit}px;
|
||||
border-top: 1px solid ${theme.colorSplit};
|
||||
border-top: 1px solid ${theme.colors.grayscale.light3};
|
||||
`}
|
||||
`;
|
||||
|
||||
@@ -132,7 +132,7 @@ const VirtualTable = <RecordType extends object>(
|
||||
if (gridRef.current) {
|
||||
return gridRef.current?.state?.scrollLeft;
|
||||
}
|
||||
return 0;
|
||||
return null;
|
||||
},
|
||||
set: (scrollLeft: number) => {
|
||||
if (gridRef.current) {
|
||||
|
||||
@@ -20,7 +20,7 @@ import { styled } from '../../../..';
|
||||
import { Constants } from '../../..';
|
||||
|
||||
const GrayCell = styled.span`
|
||||
color: ${({ theme }) => theme.colorTextSecondary};
|
||||
color: ${({ theme }) => theme.colors.grayscale.light1};
|
||||
`;
|
||||
|
||||
function NullCell() {
|
||||
|
||||
@@ -74,7 +74,7 @@ function HeaderWithRadioGroup(props: HeaderWithRadioGroupProps) {
|
||||
>
|
||||
<Icons.SettingOutlined
|
||||
iconSize="m"
|
||||
iconColor={theme.colorIcon}
|
||||
iconColor={theme.colors.grayscale.light1}
|
||||
css={css`
|
||||
margin-top: ${theme.sizeUnit * 0.75}px;
|
||||
margin-right: ${theme.sizeUnit}px;
|
||||
|
||||
@@ -52,9 +52,7 @@ interface TableCollectionProps<T extends object> {
|
||||
const StyledTable = styled(Table)`
|
||||
${({ theme }) => `
|
||||
th.ant-column-cell {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
min-width: fit-content;
|
||||
}
|
||||
.actions {
|
||||
opacity: 0;
|
||||
@@ -85,6 +83,7 @@ const StyledTable = styled(Table)`
|
||||
font-feature-settings: 'tnum' 1;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
max-width: 320px;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
padding-left: ${theme.sizeUnit * 4}px;
|
||||
@@ -150,7 +149,7 @@ function TableCollection<T extends object>({
|
||||
size={size}
|
||||
data-test="listview-table"
|
||||
pagination={false}
|
||||
tableLayout="fixed"
|
||||
tableLayout="auto"
|
||||
rowKey="rowId"
|
||||
rowSelection={rowSelection}
|
||||
locale={{ emptyText: null }}
|
||||
|
||||
@@ -94,7 +94,7 @@ export function mapColumns<T extends object>(
|
||||
dataIndex: column.id?.includes('.') ? column.id.split('.') : column.id,
|
||||
hidden: column.hidden,
|
||||
key: column.id,
|
||||
width: column.size ? COLUMN_SIZE_MAP[column.size] : COLUMN_SIZE_MAP.md,
|
||||
minWidth: column.size ? COLUMN_SIZE_MAP[column.size] : COLUMN_SIZE_MAP.md,
|
||||
ellipsis: !columnsForWrapText?.includes(column.id),
|
||||
defaultSortOrder: (isSorted
|
||||
? isSortedDesc
|
||||
|
||||
@@ -83,7 +83,7 @@ const Tabs = Object.assign(StyledTabs, {
|
||||
const StyledEditableTabs = styled(StyledTabs)`
|
||||
${({ theme }) => `
|
||||
.ant-tabs-content-holder {
|
||||
background: ${theme.colorBgContainer};
|
||||
background: ${theme.colors.grayscale.light5};
|
||||
}
|
||||
|
||||
& > .ant-tabs-nav {
|
||||
@@ -99,7 +99,7 @@ const StyledEditableTabs = styled(StyledTabs)`
|
||||
`;
|
||||
|
||||
const StyledCloseOutlined = styled(Icons.CloseOutlined)`
|
||||
color: ${({ theme }) => theme.colorIcon};
|
||||
color: ${({ theme }) => theme.colors.grayscale.base};
|
||||
`;
|
||||
export const EditableTabs = Object.assign(StyledEditableTabs, {
|
||||
TabPane: StyledTabPane,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { render } from '@superset-ui/core/spec';
|
||||
import { TelemetryPixel } from '.';
|
||||
import TelemetryPixel from '.';
|
||||
|
||||
const OLD_ENV = process.env;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ interface TelemetryPixelProps {
|
||||
|
||||
const PIXEL_ID = '0d3461e1-abb1-4691-a0aa-5ed50de66af0';
|
||||
|
||||
export const TelemetryPixel = ({
|
||||
const TelemetryPixel = ({
|
||||
version = 'unknownVersion',
|
||||
sha = 'unknownSHA',
|
||||
build = 'unknownBuild',
|
||||
@@ -56,3 +56,4 @@ export const TelemetryPixel = ({
|
||||
/>
|
||||
);
|
||||
};
|
||||
export default TelemetryPixel;
|
||||
|
||||
@@ -16,124 +16,101 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { useMemo } from 'react';
|
||||
import { Icons } from '@superset-ui/core/components';
|
||||
import { Dropdown, Icons } from '@superset-ui/core/components';
|
||||
import type { MenuItem } from '@superset-ui/core/components/Menu';
|
||||
import { t, ThemeMode, useTheme, ThemeAlgorithm } from '@superset-ui/core';
|
||||
import { t, useTheme } from '@superset-ui/core';
|
||||
import { ThemeAlgorithm, ThemeMode } from '../../theme/types';
|
||||
|
||||
export interface ThemeSubMenuOption {
|
||||
key: ThemeMode;
|
||||
label: string;
|
||||
icon: React.ReactNode;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
export interface ThemeSubMenuProps {
|
||||
export interface ThemeSelectProps {
|
||||
setThemeMode: (newMode: ThemeMode) => void;
|
||||
tooltipTitle?: string;
|
||||
themeMode: ThemeMode;
|
||||
hasLocalOverride?: boolean;
|
||||
onClearLocalSettings?: () => void;
|
||||
allowOSPreference?: boolean;
|
||||
}
|
||||
|
||||
export const useThemeMenuItems = ({
|
||||
const ThemeSelect: React.FC<ThemeSelectProps> = ({
|
||||
setThemeMode,
|
||||
tooltipTitle = 'Select theme',
|
||||
themeMode,
|
||||
hasLocalOverride = false,
|
||||
onClearLocalSettings,
|
||||
allowOSPreference = true,
|
||||
}: ThemeSubMenuProps): MenuItem => {
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const handleSelect = (mode: ThemeMode) => {
|
||||
setThemeMode(mode);
|
||||
};
|
||||
|
||||
const themeIconMap: Record<ThemeAlgorithm | ThemeMode, React.ReactNode> =
|
||||
useMemo(
|
||||
() => ({
|
||||
[ThemeAlgorithm.DEFAULT]: <Icons.SunOutlined />,
|
||||
[ThemeAlgorithm.DARK]: <Icons.MoonOutlined />,
|
||||
[ThemeMode.SYSTEM]: <Icons.FormatPainterOutlined />,
|
||||
[ThemeAlgorithm.COMPACT]: <Icons.CompressOutlined />,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
const themeIconMap: Record<ThemeAlgorithm | ThemeMode, React.ReactNode> = {
|
||||
[ThemeAlgorithm.DEFAULT]: <Icons.SunOutlined />,
|
||||
[ThemeAlgorithm.DARK]: <Icons.MoonOutlined />,
|
||||
[ThemeMode.SYSTEM]: <Icons.FormatPainterOutlined />,
|
||||
[ThemeAlgorithm.COMPACT]: <Icons.CompressOutlined />,
|
||||
};
|
||||
|
||||
const selectedThemeModeIcon = useMemo(
|
||||
() =>
|
||||
hasLocalOverride ? (
|
||||
<Icons.FormatPainterOutlined style={{ color: theme.colorError }} />
|
||||
) : (
|
||||
themeIconMap[themeMode]
|
||||
),
|
||||
[hasLocalOverride, theme.colorError, themeIconMap, themeMode],
|
||||
// Use different icon when local theme is active
|
||||
const triggerIcon = hasLocalOverride ? (
|
||||
<Icons.FormatPainterOutlined style={{ color: theme.colorErrorText }} />
|
||||
) : (
|
||||
themeIconMap[themeMode] || <Icons.FormatPainterOutlined />
|
||||
);
|
||||
|
||||
const themeOptions: MenuItem[] = [
|
||||
const menuItems: MenuItem[] = [
|
||||
{
|
||||
type: 'group',
|
||||
label: t('Theme'),
|
||||
},
|
||||
{
|
||||
key: ThemeMode.DEFAULT,
|
||||
label: (
|
||||
<>
|
||||
<Icons.SunOutlined /> {t('Light')}
|
||||
</>
|
||||
),
|
||||
label: t('Light'),
|
||||
icon: <Icons.SunOutlined />,
|
||||
onClick: () => handleSelect(ThemeMode.DEFAULT),
|
||||
},
|
||||
{
|
||||
key: ThemeMode.DARK,
|
||||
label: (
|
||||
<>
|
||||
<Icons.MoonOutlined /> {t('Dark')}
|
||||
</>
|
||||
),
|
||||
label: t('Dark'),
|
||||
icon: <Icons.MoonOutlined />,
|
||||
onClick: () => handleSelect(ThemeMode.DARK),
|
||||
},
|
||||
...(allowOSPreference
|
||||
? [
|
||||
{
|
||||
key: ThemeMode.SYSTEM,
|
||||
label: (
|
||||
<>
|
||||
<Icons.FormatPainterOutlined /> {t('Match system')}
|
||||
</>
|
||||
),
|
||||
label: t('Match system'),
|
||||
icon: <Icons.FormatPainterOutlined />,
|
||||
onClick: () => handleSelect(ThemeMode.SYSTEM),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
|
||||
const children: MenuItem[] = [
|
||||
{
|
||||
type: 'group' as const,
|
||||
label: t('Theme'),
|
||||
key: 'theme-group',
|
||||
children: themeOptions,
|
||||
},
|
||||
];
|
||||
|
||||
// Add clear settings option only when there's a local theme active
|
||||
if (onClearLocalSettings && hasLocalOverride) {
|
||||
children.push({
|
||||
type: 'divider' as const,
|
||||
key: 'theme-divider',
|
||||
});
|
||||
children.push({
|
||||
key: 'clear-local',
|
||||
label: (
|
||||
<>
|
||||
<Icons.ClearOutlined /> {t('Clear local theme')}
|
||||
</>
|
||||
),
|
||||
onClick: onClearLocalSettings,
|
||||
});
|
||||
menuItems.push(
|
||||
{ type: 'divider' } as MenuItem,
|
||||
{
|
||||
key: 'clear-local',
|
||||
label: t('Clear local theme'),
|
||||
icon: <Icons.ClearOutlined />,
|
||||
onClick: onClearLocalSettings,
|
||||
} as MenuItem,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
key: 'theme-sub-menu',
|
||||
label: selectedThemeModeIcon,
|
||||
icon: <Icons.CaretDownOutlined iconSize="xs" />,
|
||||
children,
|
||||
};
|
||||
return (
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: menuItems,
|
||||
selectedKeys: [themeMode],
|
||||
}}
|
||||
trigger={['hover']}
|
||||
>
|
||||
{triggerIcon}
|
||||
</Dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeSelect;
|
||||
@@ -1,220 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { render, screen } from '@superset-ui/core/spec';
|
||||
import { AgGridReact } from 'ag-grid-react';
|
||||
import { createRef } from 'react';
|
||||
import { ThemeProvider, supersetTheme } from '../../theme';
|
||||
import { ThemedAgGridReact } from './index';
|
||||
import * as themeUtils from '../../theme/utils/themeUtils';
|
||||
|
||||
// Mock useThemeMode hook
|
||||
jest.mock('../../theme/utils/themeUtils', () => ({
|
||||
...jest.requireActual('../../theme/utils/themeUtils'),
|
||||
useThemeMode: jest.fn(() => false), // Default to light mode
|
||||
}));
|
||||
|
||||
// Mock ag-grid-react to avoid complex setup
|
||||
jest.mock('ag-grid-react', () => ({
|
||||
AgGridReact: jest.fn(({ theme, ...props }) => (
|
||||
<div
|
||||
data-test="ag-grid-react"
|
||||
data-theme={JSON.stringify(theme)}
|
||||
{...props}
|
||||
>
|
||||
AgGrid Mock
|
||||
</div>
|
||||
)),
|
||||
}));
|
||||
|
||||
// Mock ag-grid-community
|
||||
jest.mock('ag-grid-community', () => ({
|
||||
themeQuartz: {
|
||||
withPart: jest.fn().mockReturnThis(),
|
||||
withParams: jest.fn(params => ({ ...params, _type: 'theme' })),
|
||||
},
|
||||
colorSchemeDark: { _type: 'dark' },
|
||||
colorSchemeLight: { _type: 'light' },
|
||||
AllCommunityModule: {},
|
||||
ClientSideRowModelModule: {},
|
||||
ModuleRegistry: { registerModules: jest.fn() },
|
||||
}));
|
||||
|
||||
const mockRowData = [
|
||||
{ id: 1, name: 'Test 1' },
|
||||
{ id: 2, name: 'Test 2' },
|
||||
];
|
||||
|
||||
const mockColumnDefs = [
|
||||
{ field: 'id', headerName: 'ID' },
|
||||
{ field: 'name', headerName: 'Name' },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
// Reset to light mode by default
|
||||
(themeUtils.useThemeMode as jest.Mock).mockReturnValue(false);
|
||||
});
|
||||
|
||||
test('renders the AgGridReact component', () => {
|
||||
render(
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('ag-grid-react')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('applies light theme when background is light', () => {
|
||||
const lightTheme = {
|
||||
...supersetTheme,
|
||||
colorBgBase: '#ffffff',
|
||||
colorText: '#000000',
|
||||
};
|
||||
|
||||
render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />
|
||||
</ThemeProvider>,
|
||||
);
|
||||
|
||||
const agGrid = screen.getByTestId('ag-grid-react');
|
||||
const theme = JSON.parse(agGrid.getAttribute('data-theme') || '{}');
|
||||
|
||||
expect(theme.browserColorScheme).toBe('light');
|
||||
expect(theme.foregroundColor).toBe('#000000');
|
||||
});
|
||||
|
||||
test('applies dark theme when background is dark', () => {
|
||||
// Mock dark mode
|
||||
(themeUtils.useThemeMode as jest.Mock).mockReturnValue(true);
|
||||
|
||||
const darkTheme = {
|
||||
...supersetTheme,
|
||||
colorBgBase: '#1a1a1a',
|
||||
colorText: '#ffffff',
|
||||
};
|
||||
|
||||
render(
|
||||
<ThemeProvider theme={darkTheme}>
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />
|
||||
</ThemeProvider>,
|
||||
);
|
||||
|
||||
const agGrid = screen.getByTestId('ag-grid-react');
|
||||
const theme = JSON.parse(agGrid.getAttribute('data-theme') || '{}');
|
||||
|
||||
expect(theme.browserColorScheme).toBe('dark');
|
||||
expect(theme.foregroundColor).toBe('#ffffff');
|
||||
});
|
||||
|
||||
test('forwards ref to AgGridReact', () => {
|
||||
const ref = createRef<AgGridReact>();
|
||||
|
||||
render(
|
||||
<ThemedAgGridReact
|
||||
ref={ref}
|
||||
rowData={mockRowData}
|
||||
columnDefs={mockColumnDefs}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Check that AgGridReact was called with the ref
|
||||
expect(AgGridReact).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
rowData: mockRowData,
|
||||
columnDefs: mockColumnDefs,
|
||||
}),
|
||||
expect.any(Object), // ref is passed as second argument
|
||||
);
|
||||
});
|
||||
|
||||
test('passes all props through to AgGridReact', () => {
|
||||
const onGridReady = jest.fn();
|
||||
const onCellClicked = jest.fn();
|
||||
|
||||
render(
|
||||
<ThemedAgGridReact
|
||||
rowData={mockRowData}
|
||||
columnDefs={mockColumnDefs}
|
||||
onGridReady={onGridReady}
|
||||
onCellClicked={onCellClicked}
|
||||
pagination
|
||||
paginationPageSize={10}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(AgGridReact).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
rowData: mockRowData,
|
||||
columnDefs: mockColumnDefs,
|
||||
onGridReady,
|
||||
onCellClicked,
|
||||
pagination: true,
|
||||
paginationPageSize: 10,
|
||||
}),
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
|
||||
test('applies custom theme colors from Superset theme', () => {
|
||||
const customTheme = {
|
||||
...supersetTheme,
|
||||
colorFillTertiary: '#e5e5e5',
|
||||
colorSplit: '#d9d9d9',
|
||||
};
|
||||
|
||||
render(
|
||||
<ThemeProvider theme={customTheme}>
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />
|
||||
</ThemeProvider>,
|
||||
);
|
||||
|
||||
const agGrid = screen.getByTestId('ag-grid-react');
|
||||
const theme = JSON.parse(agGrid.getAttribute('data-theme') || '{}');
|
||||
|
||||
// Just verify a couple key theme properties are applied
|
||||
expect(theme.headerBackgroundColor).toBe('#e5e5e5');
|
||||
expect(theme.borderColor).toBe('#d9d9d9');
|
||||
});
|
||||
|
||||
test('wraps component with proper container div', () => {
|
||||
const { container } = render(
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />,
|
||||
);
|
||||
|
||||
const wrapper = container.querySelector('[data-themed-ag-grid="true"]');
|
||||
expect(wrapper).toBeInTheDocument();
|
||||
// Styles are now applied via css prop, not inline styles
|
||||
expect(wrapper).toHaveAttribute('data-themed-ag-grid', 'true');
|
||||
});
|
||||
|
||||
test('handles missing theme gracefully', () => {
|
||||
const incompleteTheme = {
|
||||
...supersetTheme,
|
||||
colorBgBase: undefined,
|
||||
};
|
||||
|
||||
render(
|
||||
<ThemeProvider theme={incompleteTheme}>
|
||||
<ThemedAgGridReact rowData={mockRowData} columnDefs={mockColumnDefs} />
|
||||
</ThemeProvider>,
|
||||
);
|
||||
|
||||
// Should still render without crashing
|
||||
expect(screen.getByTestId('ag-grid-react')).toBeInTheDocument();
|
||||
});
|
||||
@@ -1,190 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { useMemo, forwardRef } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { AgGridReact, type AgGridReactProps } from 'ag-grid-react';
|
||||
import {
|
||||
themeQuartz,
|
||||
colorSchemeDark,
|
||||
colorSchemeLight,
|
||||
} from 'ag-grid-community';
|
||||
import { useTheme } from '../../theme';
|
||||
import { useThemeMode } from '../../theme/utils/themeUtils';
|
||||
|
||||
// Note: With ag-grid v34's new theming API, CSS files are injected automatically
|
||||
// Do NOT import 'ag-grid-community/styles/ag-grid.css' or theme CSS files
|
||||
|
||||
export interface ThemedAgGridReactProps extends AgGridReactProps {
|
||||
/**
|
||||
* Optional theme parameter overrides to customize specific ag-grid theme values.
|
||||
* These will be merged with the default Superset theme values.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <ThemedAgGridReact
|
||||
* rowData={data}
|
||||
* columnDefs={columns}
|
||||
* themeOverrides={{
|
||||
* headerBackgroundColor: '#custom-color',
|
||||
* fontSize: 14,
|
||||
* }}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
themeOverrides?: Record<string, any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* ThemedAgGridReact - A wrapper around AgGridReact that applies Superset theming
|
||||
*
|
||||
* This component:
|
||||
* - Preserves the full AgGridReactProps interface for drop-in replacement
|
||||
* - Applies Superset theme variables via ag-grid's JavaScript theming API
|
||||
* - Supports automatic dark/light mode switching
|
||||
* - Allows custom theme parameter overrides
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <ThemedAgGridReact
|
||||
* rowData={data}
|
||||
* columnDefs={columns}
|
||||
* themeOverrides={{ fontSize: 14 }}
|
||||
* // ... any other AgGridReactProps
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export const ThemedAgGridReact = forwardRef<
|
||||
AgGridReact,
|
||||
ThemedAgGridReactProps
|
||||
>(function ThemedAgGridReact({ themeOverrides, ...props }, ref) {
|
||||
const theme = useTheme();
|
||||
const isDarkMode = useThemeMode();
|
||||
|
||||
// Get the appropriate ag-grid theme based on dark/light mode
|
||||
const agGridTheme = useMemo(() => {
|
||||
// Use quaternary fill for odd rows
|
||||
const oddRowBg = theme?.colorFillQuaternary;
|
||||
|
||||
const baseTheme = isDarkMode
|
||||
? themeQuartz.withPart(colorSchemeDark)
|
||||
: themeQuartz.withPart(colorSchemeLight);
|
||||
|
||||
// Use withParams to set colors directly via ag-grid's API
|
||||
const params = {
|
||||
// Core colors
|
||||
backgroundColor: 'transparent',
|
||||
foregroundColor: theme.colorText,
|
||||
browserColorScheme: isDarkMode ? 'dark' : 'light',
|
||||
|
||||
// Header styling
|
||||
headerBackgroundColor: theme.colorFillTertiary,
|
||||
headerTextColor: theme.colorTextHeading,
|
||||
|
||||
// Cell and row styling
|
||||
oddRowBackgroundColor: oddRowBg,
|
||||
rowHoverColor: theme.colorFillSecondary,
|
||||
selectedRowBackgroundColor: theme.colorPrimaryBg,
|
||||
cellTextColor: theme.colorText,
|
||||
|
||||
// Borders
|
||||
borderColor: theme.colorSplit,
|
||||
columnBorderColor: theme.colorSplit,
|
||||
|
||||
// Interactive elements
|
||||
accentColor: theme.colorPrimary,
|
||||
rangeSelectionBorderColor: theme.colorPrimary,
|
||||
rangeSelectionBackgroundColor: theme.colorPrimaryBg,
|
||||
|
||||
// Input fields (for filters)
|
||||
inputBackgroundColor: theme.colorBgContainer,
|
||||
inputBorderColor: theme.colorSplit,
|
||||
inputTextColor: theme.colorText,
|
||||
inputPlaceholderTextColor: theme.colorTextPlaceholder,
|
||||
|
||||
// Typography
|
||||
fontFamily: theme.fontFamily,
|
||||
fontSize: theme.fontSizeSM,
|
||||
|
||||
// Spacing
|
||||
spacing: theme.sizeUnit,
|
||||
};
|
||||
|
||||
// Only apply params if we have a valid theme
|
||||
if (!theme || !theme.colorBgBase) {
|
||||
return baseTheme;
|
||||
}
|
||||
|
||||
// Merge theme overrides if provided
|
||||
const finalParams = themeOverrides
|
||||
? { ...params, ...themeOverrides }
|
||||
: params;
|
||||
|
||||
return baseTheme.withParams(finalParams);
|
||||
}, [theme, isDarkMode, themeOverrides]);
|
||||
|
||||
return (
|
||||
<div
|
||||
css={css`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.ag-cell {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
`}
|
||||
data-themed-ag-grid="true"
|
||||
>
|
||||
<AgGridReact ref={ref} theme={agGridTheme} {...props} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
// Re-export commonly used types for convenience
|
||||
export type { CustomCellRendererProps } from 'ag-grid-react';
|
||||
|
||||
// Re-export commonly used ag-grid-community types
|
||||
export type {
|
||||
ColDef,
|
||||
Column,
|
||||
GridOptions,
|
||||
GridState,
|
||||
GridReadyEvent,
|
||||
CellClickedEvent,
|
||||
CellClassParams,
|
||||
IMenuActionParams,
|
||||
IHeaderParams,
|
||||
SortModelItem,
|
||||
ValueFormatterParams,
|
||||
ValueGetterParams,
|
||||
} from 'ag-grid-community';
|
||||
|
||||
// Re-export modules and themes commonly used with ThemedAgGridReact
|
||||
export {
|
||||
AllCommunityModule,
|
||||
ClientSideRowModelModule,
|
||||
ModuleRegistry,
|
||||
themeQuartz,
|
||||
colorSchemeDark,
|
||||
colorSchemeLight,
|
||||
} from 'ag-grid-community';
|
||||
|
||||
// Re-export AgGridReact for ref types
|
||||
export { AgGridReact } from 'ag-grid-react';
|
||||
|
||||
// Export the setup function for AG-Grid modules
|
||||
export { setupAGGridModules } from './setupAGGridModules';
|
||||
@@ -79,7 +79,7 @@ const StyledVisibleItem = styled.span`
|
||||
|
||||
const StyledTooltipItem = styled.div`
|
||||
.link {
|
||||
color: ${({ theme }) => theme.colorTextTertiary};
|
||||
color: ${({ theme }) => theme.colors.grayscale.light5};
|
||||
display: block;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,14 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { t } from '@superset-ui/core';
|
||||
import { Icons, Modal, Typography, Button } from '@superset-ui/core/components';
|
||||
import { t, css, useTheme } from '@superset-ui/core';
|
||||
import {
|
||||
Icons,
|
||||
Modal,
|
||||
Typography,
|
||||
Button,
|
||||
Flex,
|
||||
} from '@superset-ui/core/components';
|
||||
import type { FC, ReactElement } from 'react';
|
||||
|
||||
export type UnsavedChangesModalProps = {
|
||||
@@ -36,30 +42,66 @@ export const UnsavedChangesModal: FC<UnsavedChangesModalProps> = ({
|
||||
onConfirmNavigation,
|
||||
title = 'Unsaved Changes',
|
||||
body = "If you don't save, changes will be lost.",
|
||||
}: UnsavedChangesModalProps): ReactElement => (
|
||||
<Modal
|
||||
centered
|
||||
responsive
|
||||
onHide={onHide}
|
||||
show={showModal}
|
||||
width="444px"
|
||||
title={
|
||||
<>
|
||||
<Icons.WarningOutlined iconSize="m" style={{ marginRight: 8 }} />
|
||||
{title}
|
||||
</>
|
||||
}
|
||||
footer={
|
||||
<>
|
||||
<Button buttonStyle="secondary" onClick={onConfirmNavigation}>
|
||||
{t('Discard')}
|
||||
</Button>
|
||||
<Button buttonStyle="primary" onClick={handleSave}>
|
||||
{t('Save')}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Typography.Text>{body}</Typography.Text>
|
||||
</Modal>
|
||||
);
|
||||
}): ReactElement => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Modal
|
||||
name={title}
|
||||
centered
|
||||
responsive
|
||||
onHide={onHide}
|
||||
show={showModal}
|
||||
width="444px"
|
||||
title={
|
||||
<Flex>
|
||||
<Icons.WarningOutlined
|
||||
iconColor={theme.colorWarning}
|
||||
css={css`
|
||||
margin-right: ${theme.sizeUnit * 2}px;
|
||||
`}
|
||||
iconSize="l"
|
||||
/>
|
||||
<Typography.Title
|
||||
css={css`
|
||||
&& {
|
||||
margin: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
`}
|
||||
level={5}
|
||||
>
|
||||
{title}
|
||||
</Typography.Title>
|
||||
</Flex>
|
||||
}
|
||||
footer={
|
||||
<Flex
|
||||
justify="flex-end"
|
||||
css={css`
|
||||
width: 100%;
|
||||
`}
|
||||
>
|
||||
<Button
|
||||
htmlType="button"
|
||||
buttonSize="small"
|
||||
buttonStyle="secondary"
|
||||
onClick={onConfirmNavigation}
|
||||
>
|
||||
{t('Discard')}
|
||||
</Button>
|
||||
<Button
|
||||
htmlType="button"
|
||||
buttonSize="small"
|
||||
buttonStyle="primary"
|
||||
onClick={handleSave}
|
||||
>
|
||||
{t('Save')}
|
||||
</Button>
|
||||
</Flex>
|
||||
}
|
||||
>
|
||||
<Typography.Text>{body}</Typography.Text>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -66,12 +66,6 @@ export {
|
||||
type CheckboxProps,
|
||||
type CheckboxChangeEvent,
|
||||
} from './Checkbox';
|
||||
export {
|
||||
ColorPicker,
|
||||
type ColorPickerProps,
|
||||
type RGBColor,
|
||||
type ColorValue,
|
||||
} from './ColorPicker';
|
||||
export {
|
||||
Collapse,
|
||||
type CollapseProps,
|
||||
@@ -82,7 +76,6 @@ export { CronPicker, type CronError } from './CronPicker';
|
||||
export * from './DatePicker';
|
||||
export { DeleteModal, type DeleteModalProps } from './DeleteModal';
|
||||
export { Divider, type DividerProps } from './Divider';
|
||||
export { Drawer, type DrawerProps } from './Drawer';
|
||||
export {
|
||||
Dropdown,
|
||||
MenuDotsDropdown,
|
||||
@@ -171,12 +164,6 @@ export * from './Steps';
|
||||
export * from './Table';
|
||||
export * from './TableView';
|
||||
export * from './Tag';
|
||||
export * from './TelemetryPixel';
|
||||
export * from './UnsavedChangesModal';
|
||||
export * from './constants';
|
||||
export * from './Result';
|
||||
export {
|
||||
ThemedAgGridReact,
|
||||
type ThemedAgGridReactProps,
|
||||
setupAGGridModules,
|
||||
} from './ThemedAgGridReact';
|
||||
|
||||
@@ -115,15 +115,11 @@ export default class SupersetClientClass {
|
||||
return this.getCSRFToken();
|
||||
}
|
||||
|
||||
async postForm(
|
||||
endpoint: string,
|
||||
payload: Record<string, any>,
|
||||
target = '_blank',
|
||||
) {
|
||||
if (endpoint) {
|
||||
async postForm(url: string, payload: Record<string, any>, target = '_blank') {
|
||||
if (url) {
|
||||
await this.ensureAuth();
|
||||
const hiddenForm = document.createElement('form');
|
||||
hiddenForm.action = this.getUrl({ endpoint });
|
||||
hiddenForm.action = url;
|
||||
hiddenForm.method = 'POST';
|
||||
hiddenForm.target = target;
|
||||
const payloadWithToken: Record<string, any> = {
|
||||
|
||||
@@ -158,10 +158,31 @@ export function isTableAnnotationLayer(
|
||||
return layer.sourceType === AnnotationSourceType.Table;
|
||||
}
|
||||
|
||||
export type AnnotationResult = {
|
||||
records?: DataRecord[];
|
||||
export type RecordAnnotationResult = {
|
||||
records: DataRecord[];
|
||||
};
|
||||
|
||||
export type TimeseriesAnnotationResult = {
|
||||
key: string;
|
||||
values: { x: string | number; y?: number }[];
|
||||
}[];
|
||||
|
||||
export type AnnotationResult =
|
||||
| RecordAnnotationResult
|
||||
| TimeseriesAnnotationResult;
|
||||
|
||||
export function isTimeseriesAnnotationResult(
|
||||
result: AnnotationResult,
|
||||
): result is TimeseriesAnnotationResult {
|
||||
return Array.isArray(result);
|
||||
}
|
||||
|
||||
export function isRecordAnnotationResult(
|
||||
result: any,
|
||||
): result is RecordAnnotationResult {
|
||||
return Array.isArray(result?.records);
|
||||
}
|
||||
|
||||
export type AnnotationData = { [key: string]: AnnotationResult };
|
||||
|
||||
export type Annotation = {
|
||||
|
||||
@@ -204,8 +204,6 @@ export interface SqlaFormData extends BaseFormData {
|
||||
|
||||
export type QueryFormData = SqlaFormData;
|
||||
|
||||
export type LatestQueryFormData = Partial<QueryFormData>;
|
||||
|
||||
//---------------------------------------------------
|
||||
// Type guards
|
||||
//---------------------------------------------------
|
||||
|
||||
@@ -58,9 +58,8 @@ describe('Theme', () => {
|
||||
// Verify default font family is set
|
||||
expect(theme.theme.fontFamily).toContain('Inter');
|
||||
|
||||
// Verify the theme is initialized with semantic color tokens
|
||||
expect(theme.theme.colorText).toBeDefined();
|
||||
expect(theme.theme.colorBgBase).toBeDefined();
|
||||
// Verify the theme is initialized with colors
|
||||
expect(theme.theme.colors).toBeDefined();
|
||||
});
|
||||
|
||||
it('creates a theme with custom tokens when provided', () => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user