mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 18:08:07 +08:00
feat!: file download in skill file tree menu
This commit is contained in:
@ -15,6 +15,7 @@ import {
|
||||
import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Confirm from '@/app/components/base/confirm'
|
||||
import { Download02 } from '@/app/components/base/icons/src/vender/solid/general'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { NODE_MENU_TYPE } from '../constants'
|
||||
import { useFileOperations } from '../hooks/use-file-operations'
|
||||
@ -52,6 +53,7 @@ const NodeMenu: FC<NodeMenuProps> = ({
|
||||
showDeleteConfirm,
|
||||
isLoading,
|
||||
isDeleting,
|
||||
handleDownload,
|
||||
handleNewFile,
|
||||
handleNewFolder,
|
||||
handleFileChange,
|
||||
@ -126,6 +128,18 @@ const NodeMenu: FC<NodeMenuProps> = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
{!isFolder && (
|
||||
<>
|
||||
<MenuItem
|
||||
icon={Download02}
|
||||
label={t('skillSidebar.menu.download')}
|
||||
onClick={handleDownload}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
<div className="my-1 h-px bg-divider-subtle" />
|
||||
</>
|
||||
)}
|
||||
|
||||
{showRenameDelete && (
|
||||
<>
|
||||
<MenuItem
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
'use client'
|
||||
|
||||
// Handles file download operation - opens download URL in new tab
|
||||
|
||||
import { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { consoleClient } from '@/service/client'
|
||||
|
||||
type UseDownloadOperationOptions = {
|
||||
appId: string
|
||||
nodeId: string
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
export function useDownloadOperation({
|
||||
appId,
|
||||
nodeId,
|
||||
onClose,
|
||||
}: UseDownloadOperationOptions) {
|
||||
const { t } = useTranslation('workflow')
|
||||
const [isDownloading, setIsDownloading] = useState(false)
|
||||
|
||||
const handleDownload = useCallback(async () => {
|
||||
if (!nodeId || !appId)
|
||||
return
|
||||
|
||||
// Close menu immediately before any async operation
|
||||
onClose()
|
||||
|
||||
setIsDownloading(true)
|
||||
try {
|
||||
const { download_url } = await consoleClient.appAsset.getFileDownloadUrl({
|
||||
params: { appId, nodeId },
|
||||
})
|
||||
|
||||
// Open download URL in new tab (consistent with UnsupportedFileDownload)
|
||||
if (typeof window !== 'undefined')
|
||||
window.open(download_url, '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
catch {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: t('skillSidebar.menu.downloadError'),
|
||||
})
|
||||
}
|
||||
finally {
|
||||
setIsDownloading(false)
|
||||
}
|
||||
}, [appId, nodeId, onClose, t])
|
||||
|
||||
return {
|
||||
handleDownload,
|
||||
isDownloading,
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { useWorkflowStore } from '@/app/components/workflow/store'
|
||||
import { toApiParentId } from '../utils/tree-utils'
|
||||
import { useCreateOperations } from './use-create-operations'
|
||||
import { useDownloadOperation } from './use-download-operation'
|
||||
import { useModifyOperations } from './use-modify-operations'
|
||||
import { useSkillAssetTreeData } from './use-skill-asset-tree'
|
||||
|
||||
@ -51,6 +52,12 @@ export function useFileOperations({
|
||||
onClose,
|
||||
})
|
||||
|
||||
const downloadOps = useDownloadOperation({
|
||||
appId,
|
||||
nodeId,
|
||||
onClose,
|
||||
})
|
||||
|
||||
return {
|
||||
// Create operations
|
||||
fileInputRef: createOps.fileInputRef,
|
||||
@ -67,8 +74,12 @@ export function useFileOperations({
|
||||
handleDeleteConfirm: modifyOps.handleDeleteConfirm,
|
||||
handleDeleteCancel: modifyOps.handleDeleteCancel,
|
||||
|
||||
// Download operation
|
||||
handleDownload: downloadOps.handleDownload,
|
||||
|
||||
// Combined loading states
|
||||
isLoading: createOps.isCreating || modifyOps.isDeleting,
|
||||
isLoading: createOps.isCreating || modifyOps.isDeleting || downloadOps.isDownloading,
|
||||
isDeleting: modifyOps.isDeleting,
|
||||
isDownloading: downloadOps.isDownloading,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user