diff --git a/web/app/components/workflow/skill/file-tree/artifacts-section.tsx b/web/app/components/workflow/skill/file-tree/artifacts-section.tsx index f75817e879..bd1f651d3f 100644 --- a/web/app/components/workflow/skill/file-tree/artifacts-section.tsx +++ b/web/app/components/workflow/skill/file-tree/artifacts-section.tsx @@ -26,7 +26,7 @@ const ArtifactsSection = ({ className }: ArtifactsSectionProps) => { const { data: treeData, hasFiles, isLoading } = useSandboxFilesTree(sandboxId) - const downloadMutation = useDownloadSandboxFile(sandboxId) + const { mutateAsync: fetchDownloadUrl, isPending: isDownloading } = useDownloadSandboxFile(sandboxId) const storeApi = useWorkflowStore() const selectedArtifactPath = useStore(s => s.selectedArtifactPath) @@ -40,13 +40,13 @@ const ArtifactsSection = ({ className }: ArtifactsSectionProps) => { const handleDownload = useCallback(async (node: SandboxFileTreeNode) => { try { - const ticket = await downloadMutation.mutateAsync(node.path) + const ticket = await fetchDownloadUrl(node.path) downloadUrl({ url: ticket.download_url, fileName: node.name }) } catch (error) { console.error('Download failed:', error) } - }, [downloadMutation]) + }, [fetchDownloadUrl]) const showBlueDot = !isExpanded && hasFiles const showSpinner = isLoading @@ -100,7 +100,7 @@ const ArtifactsSection = ({ className }: ArtifactsSectionProps) => { onDownload={handleDownload} onSelect={handleSelect} selectedPath={selectedArtifactPath ?? undefined} - isDownloading={downloadMutation.isPending} + isDownloading={isDownloading} /> ) : ( diff --git a/web/app/components/workflow/variable-inspect/artifacts-tab.tsx b/web/app/components/workflow/variable-inspect/artifacts-tab.tsx index d4de3539f8..9f92b7b421 100644 --- a/web/app/components/workflow/variable-inspect/artifacts-tab.tsx +++ b/web/app/components/workflow/variable-inspect/artifacts-tab.tsx @@ -61,7 +61,7 @@ const ArtifactsTab = (headerProps: InspectHeaderProps) => { const { data: treeData, hasFiles, isLoading } = useSandboxFilesTree(sandboxId, { enabled: !!sandboxId, }) - const downloadMutation = useDownloadSandboxFile(sandboxId) + const { mutateAsync: fetchDownloadUrl, isPending: isDownloading } = useDownloadSandboxFile(sandboxId) const [selectedFile, setSelectedFile] = useState(null) const { data: downloadUrlData, isLoading: isDownloadUrlLoading } = useSandboxFileDownloadUrl( sandboxId, @@ -73,16 +73,20 @@ const ArtifactsTab = (headerProps: InspectHeaderProps) => { setSelectedFile(node) }, []) - const { mutateAsync: downloadFile } = downloadMutation - const handleDownload = useCallback(async (node: SandboxFileTreeNode) => { + const handleTreeDownload = useCallback(async (node: SandboxFileTreeNode) => { try { - const ticket = await downloadFile(node.path) + const ticket = await fetchDownloadUrl(node.path) downloadUrl({ url: ticket.download_url, fileName: node.name }) } catch (error) { console.error('Download failed:', error) } - }, [downloadFile]) + }, [fetchDownloadUrl]) + + const handleSelectedFileDownload = useCallback(() => { + if (downloadUrlData?.download_url && selectedFile) + downloadUrl({ url: downloadUrlData.download_url, fileName: selectedFile.name }) + }, [downloadUrlData, selectedFile]) if (isLoading) { return ( @@ -119,10 +123,10 @@ const ArtifactsTab = (headerProps: InspectHeaderProps) => {
)} @@ -160,8 +164,8 @@ const ArtifactsTab = (headerProps: InspectHeaderProps) => {
handleDownload(file)} - disabled={downloadMutation.isPending} + onClick={handleSelectedFileDownload} + disabled={!downloadUrlData?.download_url} aria-label={`Download ${file.name}`} > diff --git a/web/service/use-sandbox-file.ts b/web/service/use-sandbox-file.ts index 9603f8d20c..0256d366b9 100644 --- a/web/service/use-sandbox-file.ts +++ b/web/service/use-sandbox-file.ts @@ -3,10 +3,7 @@ import type { SandboxFileNode, SandboxFileTreeNode, } from '@/types/sandbox-file' -import { - useMutation, - useQuery, -} from '@tanstack/react-query' +import { useMutation, useQuery } from '@tanstack/react-query' import { useMemo } from 'react' import { consoleClient, consoleQuery } from '@/service/client' @@ -39,20 +36,6 @@ export function useGetSandboxFiles( }) } -export function useDownloadSandboxFile(sandboxId: string | undefined) { - return useMutation({ - mutationKey: consoleQuery.sandboxFile.downloadFile.mutationKey(), - mutationFn: (path: string) => { - if (!sandboxId) - throw new Error('sandboxId is required') - return consoleClient.sandboxFile.downloadFile({ - params: { sandboxId }, - body: { path }, - }) - }, - }) -} - export function useSandboxFileDownloadUrl( sandboxId: string | undefined, path: string | undefined, @@ -67,6 +50,19 @@ export function useSandboxFileDownloadUrl( }) } +export function useDownloadSandboxFile(sandboxId: string | undefined) { + return useMutation({ + mutationFn: (path: string) => { + if (!sandboxId) + throw new Error('sandboxId is required') + return consoleClient.sandboxFile.downloadFile({ + params: { sandboxId }, + body: { path }, + }) + }, + }) +} + function buildTreeFromFlatList(nodes: SandboxFileNode[]): SandboxFileTreeNode[] { const nodeMap = new Map() const roots: SandboxFileTreeNode[] = []