You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2025/12/19 14:43:45 UTC
(superset) 04/07: fix: PWA file handler installation and routing issues
This is an automated email from the ASF dual-hosted git repository.
beto pushed a commit to branch file-handler2
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 14db9e0e8c8a6ae8d6b97162fed8f4daad880012
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Mon Dec 15 17:16:28 2025 -0500
fix: PWA file handler installation and routing issues
- Change route from /file-handler to /superset/file-handler to match Flask blueprint
- Add Service-Worker-Allowed header for root scope registration
- Add proper square icons (192x192, 512x512) for PWA install
- Add wide and narrow screenshots for PWA install prompt
- Update tests to use new route path
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <no...@anthropic.com>
---
.../src/assets/images/pwa/icon-192.png | Bin 0 -> 1378 bytes
.../src/assets/images/pwa/icon-512.png | Bin 0 -> 4384 bytes
.../src/assets/images/pwa/screenshot-narrow.png | Bin 0 -> 100187 bytes
.../src/assets/images/pwa/screenshot-wide.png | Bin 0 -> 253025 bytes
.../src/pages/FileHandler/index.test.tsx | 44 ++++++++++-----------
superset-frontend/src/pwa-manifest.json | 40 +++++++++++++++++--
superset-frontend/src/views/routes.tsx | 2 +-
superset/initialization/__init__.py | 7 +++-
8 files changed, 66 insertions(+), 27 deletions(-)
diff --git a/superset-frontend/src/assets/images/pwa/icon-192.png b/superset-frontend/src/assets/images/pwa/icon-192.png
new file mode 100644
index 0000000000..a53fbe7e7b
Binary files /dev/null and b/superset-frontend/src/assets/images/pwa/icon-192.png differ
diff --git a/superset-frontend/src/assets/images/pwa/icon-512.png b/superset-frontend/src/assets/images/pwa/icon-512.png
new file mode 100644
index 0000000000..320eeb6382
Binary files /dev/null and b/superset-frontend/src/assets/images/pwa/icon-512.png differ
diff --git a/superset-frontend/src/assets/images/pwa/screenshot-narrow.png b/superset-frontend/src/assets/images/pwa/screenshot-narrow.png
new file mode 100644
index 0000000000..f601594e96
Binary files /dev/null and b/superset-frontend/src/assets/images/pwa/screenshot-narrow.png differ
diff --git a/superset-frontend/src/assets/images/pwa/screenshot-wide.png b/superset-frontend/src/assets/images/pwa/screenshot-wide.png
new file mode 100644
index 0000000000..c2a3731a0e
Binary files /dev/null and b/superset-frontend/src/assets/images/pwa/screenshot-wide.png differ
diff --git a/superset-frontend/src/pages/FileHandler/index.test.tsx b/superset-frontend/src/pages/FileHandler/index.test.tsx
index 4d99471a69..b8385f1712 100644
--- a/superset-frontend/src/pages/FileHandler/index.test.tsx
+++ b/superset-frontend/src/pages/FileHandler/index.test.tsx
@@ -134,8 +134,8 @@ beforeEach(() => {
test('shows error when launchQueue is not supported', async () => {
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -154,8 +154,8 @@ test('redirects when no files are provided', async () => {
const { triggerConsumer } = setupLaunchQueue();
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -175,8 +175,8 @@ test('handles CSV file correctly', async () => {
setupLaunchQueue(fileHandle);
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -196,8 +196,8 @@ test('handles Excel (.xls) file correctly', async () => {
setupLaunchQueue(fileHandle);
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -215,8 +215,8 @@ test('handles Excel (.xlsx) file correctly', async () => {
setupLaunchQueue(fileHandle);
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -234,8 +234,8 @@ test('handles Parquet file correctly', async () => {
setupLaunchQueue(fileHandle);
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -252,8 +252,8 @@ test('shows error for unsupported file type', async () => {
const { triggerConsumer } = setupLaunchQueue();
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -277,8 +277,8 @@ test('handles file with uppercase extension', async () => {
setupLaunchQueue(fileHandle);
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -294,8 +294,8 @@ test('handles errors during file processing', async () => {
const { triggerConsumer } = setupLaunchQueue();
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -324,8 +324,8 @@ test('modal close redirects to welcome page', async () => {
setupLaunchQueue(fileHandle);
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
@@ -348,8 +348,8 @@ test('shows loading state while waiting for file', () => {
setupLaunchQueue();
render(
- <MemoryRouter initialEntries={['/file-handler']}>
- <Route path="/file-handler">
+ <MemoryRouter initialEntries={['/superset/file-handler']}>
+ <Route path="/superset/file-handler">
<FileHandler />
</Route>
</MemoryRouter>,
diff --git a/superset-frontend/src/pwa-manifest.json b/superset-frontend/src/pwa-manifest.json
index 8b8755e189..fcd8f2213e 100644
--- a/superset-frontend/src/pwa-manifest.json
+++ b/superset-frontend/src/pwa-manifest.json
@@ -9,15 +9,49 @@
"theme_color": "#20a7c9",
"icons": [
{
- "src": "/static/assets/images/superset-logo-horiz.png",
- "sizes": "any",
+ "src": "/static/assets/images/pwa/icon-192.png",
+ "sizes": "192x192",
"type": "image/png",
"purpose": "any"
+ },
+ {
+ "src": "/static/assets/images/pwa/icon-512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "any"
+ },
+ {
+ "src": "/static/assets/images/pwa/icon-192.png",
+ "sizes": "192x192",
+ "type": "image/png",
+ "purpose": "maskable"
+ },
+ {
+ "src": "/static/assets/images/pwa/icon-512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "maskable"
+ }
+ ],
+ "screenshots": [
+ {
+ "src": "/static/assets/images/pwa/screenshot-wide.png",
+ "sizes": "1280x720",
+ "type": "image/png",
+ "form_factor": "wide",
+ "label": "Apache Superset Dashboard"
+ },
+ {
+ "src": "/static/assets/images/pwa/screenshot-narrow.png",
+ "sizes": "540x720",
+ "type": "image/png",
+ "form_factor": "narrow",
+ "label": "Apache Superset Mobile View"
}
],
"file_handlers": [
{
- "action": "/file-handler",
+ "action": "/superset/file-handler",
"accept": {
"text/csv": [".csv"],
"application/vnd.ms-excel": [".xls"],
diff --git a/superset-frontend/src/views/routes.tsx b/superset-frontend/src/views/routes.tsx
index eb6dbd05dd..87d38f7680 100644
--- a/superset-frontend/src/views/routes.tsx
+++ b/superset-frontend/src/views/routes.tsx
@@ -211,7 +211,7 @@ export const routes: Routes = [
Component: Home,
},
{
- path: '/file-handler',
+ path: '/superset/file-handler',
Component: FileHandler,
},
{
diff --git a/superset/initialization/__init__.py b/superset/initialization/__init__.py
index 40801225b3..206fd4e5ca 100644
--- a/superset/initialization/__init__.py
+++ b/superset/initialization/__init__.py
@@ -648,7 +648,7 @@ class SupersetAppInitializer: # pylint: disable=too-many-public-methods
def register_request_handlers(self) -> None:
"""Register app-level request handlers"""
- from flask import Response
+ from flask import request, Response
@self.superset_app.after_request
def apply_http_headers(response: Response) -> Response:
@@ -664,6 +664,11 @@ class SupersetAppInitializer: # pylint: disable=too-many-public-methods
for k, v in self.superset_app.config["DEFAULT_HTTP_HEADERS"].items():
if k not in response.headers:
response.headers[k] = v
+
+ # Allow service worker to control the root scope for PWA file handling
+ if request.path.endswith("service-worker.js"):
+ response.headers["Service-Worker-Allowed"] = "/"
+
return response
@self.superset_app.after_request