From 5708592a518800454c46ce2fd48277e9d0b8921a Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Tue, 23 Sep 2025 13:29:29 -0600 Subject: [PATCH] download metric file in three dot --- .../metrics/getMetricQueryRequests.ts | 15 +++++++- apps/web/src/api/createAxiosInstance.ts | 2 +- .../MetricDataTruncatedWarning.tsx | 30 +-------------- .../MetricViewChart/MetricViewChart.tsx | 38 +------------------ .../features/metrics/threeDotMenuHooks.tsx | 18 +++------ 5 files changed, 24 insertions(+), 79 deletions(-) diff --git a/apps/web/src/api/buster_rest/metrics/getMetricQueryRequests.ts b/apps/web/src/api/buster_rest/metrics/getMetricQueryRequests.ts index 463c3b60c..3aba175b0 100644 --- a/apps/web/src/api/buster_rest/metrics/getMetricQueryRequests.ts +++ b/apps/web/src/api/buster_rest/metrics/getMetricQueryRequests.ts @@ -18,6 +18,7 @@ import { setProtectedAssetPasswordError, useProtectedAssetPassword, } from '@/context/BusterAssets/useProtectedAssetStore'; +import { useBusterNotifications } from '@/context/BusterNotifications'; import { setOriginalMetric } from '@/context/Metrics/useOriginalMetricStore'; import { useMemoizedFn } from '@/hooks/useMemoizedFn'; import { upgradeMetricToIMetric } from '@/lib/metrics'; @@ -226,8 +227,20 @@ export const usePrefetchGetMetricDataClient = () => { ); }; -export const useDownloadMetricFile = () => { +export const useDownloadMetricFile = (downloadImmediate = true) => { + const { openInfoMessage } = useBusterNotifications(); return useMutation({ mutationFn: downloadMetricFile, + onSuccess: (data) => { + if (downloadImmediate) { + const link = document.createElement('a'); + link.href = data.downloadUrl; + link.download = ''; // This will use the filename from the response-content-disposition header + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + openInfoMessage(`Downloading ${data.rowCount} records...`); + } + }, }); }; diff --git a/apps/web/src/api/createAxiosInstance.ts b/apps/web/src/api/createAxiosInstance.ts index 513c08f43..3f09d72e9 100644 --- a/apps/web/src/api/createAxiosInstance.ts +++ b/apps/web/src/api/createAxiosInstance.ts @@ -6,7 +6,7 @@ import { Route as AuthRoute } from '@/routes/auth.login'; import { BASE_URL_V2 } from './config'; import { rustErrorHandler } from './errors'; -const AXIOS_TIMEOUT = 180000; // 3 minutes +const AXIOS_TIMEOUT = 120000; // 2 minutes export const createAxiosInstance = (baseURL = BASE_URL_V2) => { const apiInstance = axios.create({ diff --git a/apps/web/src/components/features/metrics/MetricViewChart/MetricDataTruncatedWarning.tsx b/apps/web/src/components/features/metrics/MetricViewChart/MetricDataTruncatedWarning.tsx index 4ffcda2ad..a41eafa91 100644 --- a/apps/web/src/components/features/metrics/MetricViewChart/MetricDataTruncatedWarning.tsx +++ b/apps/web/src/components/features/metrics/MetricViewChart/MetricDataTruncatedWarning.tsx @@ -1,5 +1,4 @@ import type React from 'react'; -import { useState } from 'react'; import { useDownloadMetricFile } from '@/api/buster_rest/metrics/getMetricQueryRequests'; import { Button } from '@/components/ui/buttons'; import { CircleWarning, Download4 } from '@/components/ui/icons'; @@ -16,38 +15,13 @@ export const MetricDataTruncatedWarning: React.FC { const { - mutateAsync: downloadMetricFile, + mutateAsync: handleDownload, isPending: isGettingFile, error: downloadError, } = useDownloadMetricFile(); const hasError = !!downloadError; - const handleDownload = async () => { - try { - // Create a timeout promise that rejects after 2 minutes (matching backend timeout) - const timeoutPromise = new Promise((_, reject) => { - setTimeout(() => reject(new Error('Download timeout')), 2 * 60 * 1000); // 2 minutes - }); - - // Race between the API call and the timeout - const response = (await Promise.race([ - downloadMetricFile(metricId), - timeoutPromise, - ])) as Awaited>; - - // Create a temporary anchor element to trigger download without navigation - const link = document.createElement('a'); - link.href = response.downloadUrl; - link.download = ''; // This will use the filename from the response-content-disposition header - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); - } catch (error) { - console.error('Failed to download metric file:', error); - } - }; - return (