gabotorresruiz commented on code in PR #43340:
URL: https://github.com/apache/superset/pull/43340#discussion_r3867274331


##########
superset-frontend/src/dashboard/components/menu/DownloadMenuItems/index.tsx:
##########
@@ -83,9 +89,28 @@ export const useDownloadMenuItems = (
     canExportImage,
   } = props;
 
-  const { addDangerToast, addSuccessToast } = useToasts();
+  const { addDangerToast, addSuccessToast, addInfoToast } = useToasts();
   const dataMask = useSelector((state: RootState) => state.dataMask);
-  const SCREENSHOT_NODE_SELECTOR = ".dashboard";
+  // Embedded (iframe) sessions may have no email address, so they get
+  // delivery-neutral copy and a poll window that outlives the task budget.
+  const isEmbedded = isEmbeddedDashboard();

Review Comment:
   Fixed in c75abca73a alongside the other identity comment: delivery copy and 
the poll window now follow the requester identity, so sessions the backend 
cannot email get the neutral copy and the 12 minute window. The task also 
records a running status when a worker picks the job up, and the client 
restarts its wait window on observing it, so queue delay is no longer counted 
against the export and a queued guest export is not orphaned. Jest tests cover 
both.



##########
superset-frontend/src/dashboard/components/menu/DownloadMenuItems/index.tsx:
##########
@@ -190,36 +215,37 @@ export const useDownloadMenuItems = (
           download_url: downloadUrl,
           message,
         } = json as ExportStatusResponse;
-        if (status === "ready") {
+        if (status === 'ready') {
           if (downloadUrl) {
-            window.location.href = downloadUrl;
+            redirect(downloadUrl);
           }
-          addSuccessToast(t("Your export is ready and downloading."));
+          addSuccessToast(t('Your export is ready and downloading.'));
           return;
         }
-        if (status === "error") {
+        if (status === 'error') {
           addDangerToast(
-            message || t("Sorry, something went wrong. Try again later."),
+            message || t('Sorry, something went wrong. Try again later.'),
           );
           return;
         }
-        if (Date.now() - startedAt > EXPORT_STATUS_POLL_TIMEOUT_MS) {
+        if (Date.now() - startedAt > pollTimeoutMs) {
           addDangerToast(
-            t("Your export is taking longer than expected. Try again later."),
+            t('Your export is taking longer than expected. Try again later.'),
           );
           return;
         }
+        addExportPendingToast();

Review Comment:
   Kept as is deliberately: this mirrors useDownloadScreenshot's existing 
repeating info toast with noDuplicate, and consistency between the two download 
flows matters more to us than reducing the re announcements. Happy to revisit 
both flows together in a follow up if the repetition proves to be a real 
problem.



##########
superset/dashboards/api.py:
##########
@@ -1922,17 +1937,27 @@ def download_xlsx(self, job_id: uuid.UUID) -> 
WerkzeugResponse:
             description: The job_id from the export_xlsx response
           responses:
             302:
-              description: Redirect to a pre-signed S3 download URL
+              description: Redirect to a signed storage download URL
             410:
               description: The link is unknown, expired, or the export failed
+            501:
+              description: Excel export is not configured on this server
         """
         resolved = resolve_download_link(job_id)
         if resolved is None:
             return self.response(410, message="This download link has 
expired.")
         bucket, key = resolved
-        return redirect(
-            s3.generate_presigned_url(bucket, key, PRESIGNED_URL_TTL_SECONDS)
+        storage_backend = current_app.config["EXPORT_STORAGE"].get("backend")

Review Comment:
   Addressed in c75abca73a with a deliberately minimal shape: the link record 
stores the dotted path of the uploading backend, and the download redirect 
refuses to sign when the configured backend differs, returning the same 410 as 
an expired link. Legacy records without the field keep signing with the 
configured backend. Reconstructing the original backend felt like overreach, 
since a replaced backend instance and its constructor kwargs no longer exist in 
config; failing clearly beats redirecting to a URL for the wrong provider. 
Integration tests cover the mismatch and the legacy record path.



##########
docs/docs/using-superset/exporting-dashboard-data.mdx:
##########
@@ -72,23 +91,25 @@ will not register.
 
 ## Configuration keys
 
-| Key                             | Default                | Description       
                                                                                
                                                                                
|
-| ------------------------------- | ---------------------- | 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 |
-| `EXCEL_EXPORT_S3_BUCKET`        | `None`                 | Destination 
bucket. Required; `501` if unset.                                               
                                                                                
      |
-| `EXCEL_EXPORT_S3_KEY_PREFIX`    | `"dashboard-exports/"` | Key prefix: 
`{prefix}{dashboard_id}/{job_id}.xlsx`.                                         
                                                                                
      |
-| `EXCEL_EXPORT_LINK_TTL_SECONDS` | `86400`                | Lifetime of the 
pre-signed download URL (24h).                                                  
                                                                                
  |
-| `EXCEL_EXPORT_S3_CLIENT_KWARGS` | `{}`                   | Extra kwargs for 
`boto3.client("s3", ...)` — e.g. `region_name`, or `endpoint_url` for 
MinIO/LocalStack.                                                               
           |
-| `EXCEL_EXPORT_TABLE_VIZ_TYPES`  | `None`                 | Viz types kept 
tabular in **Export Images to Excel** mode; every other type is embedded as an 
image. `None` uses the built-in default (`table`, `pivot_table`, 
`pivot_table_v2`). |
-| `EXCEL_EXPORT_QUERY_CONTEXT_BUILDER` | `None`            | Optional 
`Callable[[form_data_dict], dict \| None]` to build a query context for a chart 
missing a saved one, tried before the built-in form-data rebuild. Point it at a 
service that runs the chart's real frontend `buildQuery` to faithfully export 
viz types the built-in rebuild can't handle. Must return `None` when it can't 
build faithfully, so the export falls back. |
-
-Credentials and region resolve through the standard boto3 chain (environment
-variables, shared config, or instance role) unless overridden via
-`EXCEL_EXPORT_S3_CLIENT_KWARGS`. The worker needs `s3:PutObject` on the bucket.
+| Key                                    | Default                | 
Description                                                                     
                                                                                
                  |
+| -------------------------------------- | ---------------------- | 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 |
+| `EXPORT_STORAGE["bucket"]`             | unset                  | 
Destination bucket. Required; `501` if unset.                                   
                                                                                
                  |
+| `EXPORT_STORAGE["backend"]`            | unset                  | Storage 
backend instance: `S3ExportStorage()` (`superset.utils.s3`), 
`GCSExportStorage()` (`superset.utils.gcs`), or a custom 
`superset.utils.export_storage.ExportStorage` implementation. Required; `501` 
if unset. |

Review Comment:
   Fixed in c75abca73a: the Limitations section now documents the guest polling 
flow (auto download, no email fallback, images unavailable), and SMTP is 
documented as needed for email delivery only.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to