mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 01:48:04 +08:00
fix: upload zip not show confirm
This commit is contained in:
@ -47,10 +47,18 @@ vi.mock('../hooks/use-apps-query-state', () => ({
|
||||
}))
|
||||
|
||||
let mockOnDSLFileDropped: ((file: File) => void) | null = null
|
||||
let mockOnBundleFileDropped: ((file: File) => void) | null = null
|
||||
let mockDragging = false
|
||||
vi.mock('../hooks/use-dsl-drag-drop', () => ({
|
||||
useDSLDragDrop: ({ onDSLFileDropped }: { onDSLFileDropped: (file: File) => void }) => {
|
||||
useDSLDragDrop: ({
|
||||
onDSLFileDropped,
|
||||
onBundleFileDropped,
|
||||
}: {
|
||||
onDSLFileDropped: (file: File) => void
|
||||
onBundleFileDropped?: (file: File) => void
|
||||
}) => {
|
||||
mockOnDSLFileDropped = onDSLFileDropped
|
||||
mockOnBundleFileDropped = onBundleFileDropped ?? null
|
||||
return { dragging: mockDragging }
|
||||
},
|
||||
}))
|
||||
@ -223,6 +231,7 @@ describe('List', () => {
|
||||
mockIsCurrentWorkspaceDatasetOperator.mockReturnValue(false)
|
||||
mockDragging = false
|
||||
mockOnDSLFileDropped = null
|
||||
mockOnBundleFileDropped = null
|
||||
mockServiceState.error = null
|
||||
mockServiceState.hasNextPage = false
|
||||
mockServiceState.isLoading = false
|
||||
@ -510,6 +519,18 @@ describe('List', () => {
|
||||
expect(screen.getByTestId('create-dsl-modal')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should handle zip file drop and show modal', () => {
|
||||
renderList()
|
||||
|
||||
const mockFile = new File(['zip content'], 'bundle.zip', { type: 'application/zip' })
|
||||
act(() => {
|
||||
if (mockOnBundleFileDropped)
|
||||
mockOnBundleFileDropped(mockFile)
|
||||
})
|
||||
|
||||
expect(screen.getByTestId('create-dsl-modal')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should close DSL modal when onClose is called', () => {
|
||||
renderList()
|
||||
|
||||
|
||||
@ -5,12 +5,14 @@ import { useDSLDragDrop } from '../use-dsl-drag-drop'
|
||||
describe('useDSLDragDrop', () => {
|
||||
let container: HTMLDivElement
|
||||
let mockOnDSLFileDropped: Mock
|
||||
let mockOnBundleFileDropped: Mock
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
container = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
mockOnDSLFileDropped = vi.fn()
|
||||
mockOnBundleFileDropped = vi.fn()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
@ -195,6 +197,7 @@ describe('useDSLDragDrop', () => {
|
||||
renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
@ -214,6 +217,7 @@ describe('useDSLDragDrop', () => {
|
||||
renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
@ -233,6 +237,7 @@ describe('useDSLDragDrop', () => {
|
||||
renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
@ -247,11 +252,33 @@ describe('useDSLDragDrop', () => {
|
||||
expect(mockOnDSLFileDropped).toHaveBeenCalledWith(file)
|
||||
})
|
||||
|
||||
it('should call onBundleFileDropped for .zip file', () => {
|
||||
const containerRef = { current: container }
|
||||
renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
|
||||
const file = createMockFile('test.zip')
|
||||
const dropEvent = createDragEvent('drop', [file])
|
||||
|
||||
act(() => {
|
||||
container.dispatchEvent(dropEvent)
|
||||
})
|
||||
|
||||
expect(mockOnBundleFileDropped).toHaveBeenCalledWith(file)
|
||||
expect(mockOnDSLFileDropped).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not call onDSLFileDropped for non-yaml file', () => {
|
||||
const containerRef = { current: container }
|
||||
renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
@ -264,6 +291,7 @@ describe('useDSLDragDrop', () => {
|
||||
})
|
||||
|
||||
expect(mockOnDSLFileDropped).not.toHaveBeenCalled()
|
||||
expect(mockOnBundleFileDropped).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should set dragging to false on drop', () => {
|
||||
@ -271,6 +299,7 @@ describe('useDSLDragDrop', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
@ -294,6 +323,7 @@ describe('useDSLDragDrop', () => {
|
||||
renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
@ -324,6 +354,7 @@ describe('useDSLDragDrop', () => {
|
||||
renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
@ -386,6 +417,7 @@ describe('useDSLDragDrop', () => {
|
||||
({ enabled }) =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
enabled,
|
||||
}),
|
||||
@ -407,6 +439,7 @@ describe('useDSLDragDrop', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
@ -429,6 +462,7 @@ describe('useDSLDragDrop', () => {
|
||||
const { unmount } = renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
@ -450,6 +484,7 @@ describe('useDSLDragDrop', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useDSLDragDrop({
|
||||
onDSLFileDropped: mockOnDSLFileDropped,
|
||||
onBundleFileDropped: mockOnBundleFileDropped,
|
||||
containerRef,
|
||||
}),
|
||||
)
|
||||
|
||||
@ -18,22 +18,18 @@ import {
|
||||
import { parseAsString, useQueryState } from 'nuqs'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import Input from '@/app/components/base/input'
|
||||
import TabSliderNew from '@/app/components/base/tab-slider-new'
|
||||
import TagFilter from '@/app/components/base/tag-management/filter'
|
||||
import { useStore as useTagStore } from '@/app/components/base/tag-management/store'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import CheckboxWithLabel from '@/app/components/datasets/create/website/base/checkbox-with-label'
|
||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { CheckModal } from '@/hooks/use-pay'
|
||||
import { DSLImportStatus } from '@/models/app'
|
||||
import { fetchWorkflowOnlineUsers, importAppBundle } from '@/service/apps'
|
||||
import { fetchWorkflowOnlineUsers } from '@/service/apps'
|
||||
import { useInfiniteAppList } from '@/service/use-apps'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
import { getRedirection } from '@/utils/app-redirection'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import AppCard from './app-card'
|
||||
import { AppCardSkeleton } from './app-card-skeleton'
|
||||
@ -67,10 +63,8 @@ const List: FC<Props> = ({
|
||||
controlRefreshList = 0,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { notify } = useContext(ToastContext)
|
||||
const { systemFeatures } = useGlobalPublicStore()
|
||||
const router = useRouter()
|
||||
const { push } = useRouter()
|
||||
const { isCurrentWorkspaceEditor, isCurrentWorkspaceDatasetOperator, isLoadingCurrentWorkspace } = useAppContext()
|
||||
const showTagManagementModal = useTagStore(s => s.showTagManagementModal)
|
||||
const [activeTab, setActiveTab] = useQueryState(
|
||||
@ -98,37 +92,10 @@ const List: FC<Props> = ({
|
||||
setShowCreateFromDSLModal(true)
|
||||
}, [])
|
||||
|
||||
const [importingBundle, setImportingBundle] = useState(false)
|
||||
|
||||
const handleBundleFileDropped = useCallback(async (file: File) => {
|
||||
if (importingBundle)
|
||||
return
|
||||
setImportingBundle(true)
|
||||
try {
|
||||
const response = await importAppBundle({ file })
|
||||
const { status, app_id, app_mode } = response
|
||||
|
||||
if (status === DSLImportStatus.COMPLETED || status === DSLImportStatus.COMPLETED_WITH_WARNINGS) {
|
||||
notify({
|
||||
type: status === DSLImportStatus.COMPLETED ? 'success' : 'warning',
|
||||
message: t(status === DSLImportStatus.COMPLETED ? 'newApp.appCreated' : 'newApp.caution', { ns: 'app' }),
|
||||
})
|
||||
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
|
||||
if (app_id)
|
||||
getRedirection(isCurrentWorkspaceEditor, { id: app_id, mode: app_mode }, push)
|
||||
}
|
||||
else {
|
||||
notify({ type: 'error', message: t('importBundleFailed', { ns: 'app' }) })
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
const error = e as Error
|
||||
notify({ type: 'error', message: error.message || t('importBundleFailed', { ns: 'app' }) })
|
||||
}
|
||||
finally {
|
||||
setImportingBundle(false)
|
||||
}
|
||||
}, [importingBundle, isCurrentWorkspaceEditor, notify, push, t])
|
||||
const handleBundleFileDropped = useCallback((file: File) => {
|
||||
setDroppedDSLFile(file)
|
||||
setShowCreateFromDSLModal(true)
|
||||
}, [])
|
||||
|
||||
const { dragging } = useDSLDragDrop({
|
||||
onDSLFileDropped: handleDSLFileDropped,
|
||||
|
||||
Reference in New Issue
Block a user