feat(extensions): import/delete UI and default chatbot selection in ExtensionsList#40450
feat(extensions): import/delete UI and default chatbot selection in ExtensionsList#40450EnxDev wants to merge 7 commits into
Conversation
…sionsList Backend: - POST /api/v1/extensions/ — admin-only upload of .supx bundles (zip validation, safe-zip check, persisted to EXTENSIONS_PATH) - DELETE /api/v1/extensions/<publisher>/<name> — admin-only removal; rejects LOCAL_EXTENSIONS configured entries Frontend: - Import button in SubMenu (file picker, .supx only) calls upload endpoint - Per-row delete action with confirmation dialog - Per-row star action to set/clear default chatbot via PUT /settings; filled star indicates the active chatbot, fires notifyExtensionSettingsChanged so ChatbotMount reacts without a page reload Settings pub/sub (notifyExtensionSettingsChanged / subscribeToExtensionSettings) allows components to react to admin settings changes without a page reload. Also fix scripts/oxlint.sh: [ -n "$output" ] && echo would exit 1 under set -e when output is empty (no lint errors). Use if/fi instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Bito Automatic Review Skipped - Branch Excluded |
✅ Deploy Preview for superset-docs-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## enxdev/chat-prototype #40450 +/- ##
=========================================================
- Coverage 64.18% 63.52% -0.66%
=========================================================
Files 2592 2594 +2
Lines 139036 139284 +248
Branches 32282 32324 +42
=========================================================
- Hits 89244 88485 -759
- Misses 48260 49267 +1007
Partials 1532 1532
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
The ExtensionsList delete URL and Publisher column require a publisher field from the API, but build_extension_data did not include it. Add manifest.publisher to the response payload so the frontend can build /api/v1/extensions/<publisher>/<name> correctly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ensions The star (set as default chatbot) action in ExtensionsList is now only rendered for extensions that have registered a view at superset.chatbot. - Add subscribeToLocation / getRegisteredViewIds / getViewProvider to src/core/views/index.ts so callers can query and subscribe to the runtime view registry without depending on base-branch-only modules - ExtensionsList initialises chatbotExtensionIds from getRegisteredViewIds on mount and keeps it live via subscribeToLocation, so the star appears as soon as a chatbot extension loads without a page refresh - The star action is conditionally rendered only when isChatbot is true Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The oxlint.sh fix (set -e / [ -n "" ] false-positive exit) is unrelated to extension import/delete and should not be in this PR. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- api.py: add _validate_segment() to block path-traversal in publisher/name
params; enforce EXTENSIONS_MAX_UPLOAD_SIZE; return 409 on LOCAL_EXTENSIONS
collision; comment explains manifest-derived dest filename
- ExtensionsList.tsx: unique Tooltip ids per row (id={`...-${original.id}`});
onKeyDown Enter/Space on star and delete role=button spans; data-test attrs
for testability; remove stale loading from columns useMemo deps
- ExtensionsList.test.tsx: 10 new tests covering upload validation, delete
confirm flow, star toggle, and keyboard interaction
- tests/unit_tests/extensions/test_api.py: 19 unit tests for POST/DELETE
endpoints covering auth, validation, zip-slip, size, collision, and happy paths
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sal, tests, useCallback - Add Alembic migration for extension_settings and extension_enabled tables - Validate manifest.id segments before building dest_file path to prevent crafted bundles from escaping EXTENSIONS_PATH (defence in depth) - Add hostile manifest.id test (manifest.id='../../tmp/evil' → 400) - Add sqlite-backed round-trip tests for settings.py upsert logic - Add HTTP tests for GET/PUT /api/v1/extensions/settings endpoints - Wrap handleDelete in useCallback; add to columns useMemo deps - Fix MySQL comment drift in _upsert_settings_row (read-then-update, not merge) - Add intentional no-admin-gate comment to get_settings endpoint Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… registry API - Add deletable field to mock EXTENSIONS data - Update mock for subscribeToRegistry/getRegistryVersion replacing subscribeToLocation - Add mock for src/views/contributions CHATBOT_LOCATION - Assert delete button shown only for deletable extensions - Relax PUT settings assertion to use objectContaining Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SUMMARY
Adds three new capabilities to the Extensions management page:
Import extension — a download icon button in the SubMenu opens a file picker restricted to
.supxfiles. On selection, the file is uploaded viaPOST /api/v1/extensions/(new endpoint), validated (zip integrity + safe-zip check), and persisted toEXTENSIONS_PATH. The list refreshes automatically.Delete extension — a trash icon in the Actions column (with confirmation dialog) calls
DELETE /api/v1/extensions/<publisher>/<name>(new endpoint). Local extensions configured viaLOCAL_EXTENSIONSare rejected with a clear error. Uploaded.supxfiles are removed fromEXTENSIONS_PATH.Set default chatbot — a star icon in the Actions column calls
PUT /api/v1/extensions/settingswith the selected extension's ID asactive_chatbot_id. The filled star indicates the current active chatbot. Clicking the filled star clears the selection. The change is propagated immediately vianotifyExtensionSettingsChanged()soChatbotMountupdates without a page reload.Also includes:
notifyExtensionSettingsChanged/subscribeToExtensionSettings) insrc/core/extensionsso components can react to admin setting changes without Redux or a page reload.BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Before: Extensions list shows only extension names with no actions.


After: Extensions list has a Publisher column, an import button in the header, and per-row star (default chatbot) and trash (delete) action buttons.
TESTING INSTRUCTIONS
EXTENSIONS_PATHin yoursuperset_config.py..supxfile → the extension appears in the list.LOCAL_EXTENSIONSentry returns an appropriate error for delete (local extensions cannot be deleted through the UI).ADDITIONAL INFORMATION