mirror of
https://github.com/langgenius/dify.git
synced 2026-05-28 04:43:33 +08:00
fix: app list not refresh
This commit is contained in:
@ -12,6 +12,7 @@ const mockPush = vi.fn()
|
||||
const mockToastSuccess = vi.fn()
|
||||
const mockToastError = vi.fn()
|
||||
const mockTrackCreateApp = vi.fn()
|
||||
const mockInvalidateAppList = vi.hoisted(() => vi.fn())
|
||||
let latestDebounceFn = () => {}
|
||||
|
||||
vi.mock('ahooks', () => ({
|
||||
@ -98,6 +99,9 @@ vi.mock('@/utils/create-app-tracking', () => ({
|
||||
vi.mock('@/service/apps', () => ({
|
||||
importDSL: (...args: unknown[]) => mockImportDSL(...args),
|
||||
}))
|
||||
vi.mock('@/service/use-apps', () => ({
|
||||
useInvalidateAppList: () => mockInvalidateAppList,
|
||||
}))
|
||||
vi.mock('@/service/explore', () => ({
|
||||
fetchAppDetail: (...args: unknown[]) => mockFetchAppDetail(...args),
|
||||
}))
|
||||
@ -253,6 +257,7 @@ describe('Apps', () => {
|
||||
expect(onSuccess).toHaveBeenCalled()
|
||||
expect(mockHandleCheckPluginDependencies).toHaveBeenCalledWith('created-app-id')
|
||||
expect(localStorage.getItem(NEED_REFRESH_APP_LIST_KEY)).toBe('1')
|
||||
expect(mockInvalidateAppList).toHaveBeenCalledTimes(1)
|
||||
expect(mockGetRedirection).toHaveBeenCalledWith(true, {
|
||||
id: 'created-app-id',
|
||||
mode: AppModeEnum.CHAT,
|
||||
|
||||
@ -21,6 +21,7 @@ import { DSLImportMode } from '@/models/app'
|
||||
import { useRouter } from '@/next/navigation'
|
||||
import { importDSL } from '@/service/apps'
|
||||
import { fetchAppDetail } from '@/service/explore'
|
||||
import { useInvalidateAppList } from '@/service/use-apps'
|
||||
import { useExploreAppList } from '@/service/use-explore'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
import { getRedirection } from '@/utils/app-redirection'
|
||||
@ -45,6 +46,7 @@ const Apps = ({
|
||||
const { t } = useTranslation()
|
||||
const { isCurrentWorkspaceEditor } = useAppContext()
|
||||
const { push } = useRouter()
|
||||
const invalidateAppList = useInvalidateAppList()
|
||||
const allCategoriesEn = AppCategories.RECOMMENDED
|
||||
|
||||
const [keywords, setKeywords] = useState('')
|
||||
@ -136,6 +138,7 @@ const Apps = ({
|
||||
if (app.app_id)
|
||||
await handleCheckPluginDependencies(app.app_id)
|
||||
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
|
||||
invalidateAppList()
|
||||
getRedirection(isCurrentWorkspaceEditor, { id: app.app_id!, mode }, push)
|
||||
}
|
||||
catch {
|
||||
|
||||
@ -15,6 +15,7 @@ import CreateAppModal from '../index'
|
||||
const ahooksMocks = vi.hoisted(() => ({
|
||||
keyPressHandlers: [] as Array<() => void>,
|
||||
}))
|
||||
const mockInvalidateAppList = vi.hoisted(() => vi.fn())
|
||||
|
||||
vi.mock('ahooks', () => ({
|
||||
useDebounceFn: <T extends (...args: unknown[]) => unknown>(fn: T) => {
|
||||
@ -37,6 +38,9 @@ vi.mock('@/utils/create-app-tracking', () => ({
|
||||
vi.mock('@/service/apps', () => ({
|
||||
createApp: vi.fn(),
|
||||
}))
|
||||
vi.mock('@/service/use-apps', () => ({
|
||||
useInvalidateAppList: () => mockInvalidateAppList,
|
||||
}))
|
||||
const toastMocks = vi.hoisted(() => ({
|
||||
mockToastSuccess: vi.fn(),
|
||||
mockToastError: vi.fn(),
|
||||
@ -175,6 +179,7 @@ describe('CreateAppModal', () => {
|
||||
expect(onSuccess).toHaveBeenCalled()
|
||||
expect(onClose).toHaveBeenCalled()
|
||||
await waitFor(() => expect(mockSetItem).toHaveBeenCalledWith(NEED_REFRESH_APP_LIST_KEY, '1'))
|
||||
expect(mockInvalidateAppList).toHaveBeenCalledTimes(1)
|
||||
await waitFor(() => expect(mockGetRedirection).toHaveBeenCalledWith(true, mockApp, mockPush))
|
||||
})
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ import { useProviderContext } from '@/context/provider-context'
|
||||
import useTheme from '@/hooks/use-theme'
|
||||
import { useRouter } from '@/next/navigation'
|
||||
import { createApp } from '@/service/apps'
|
||||
import { useInvalidateAppList } from '@/service/use-apps'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
import { getRedirection } from '@/utils/app-redirection'
|
||||
import { trackCreateApp } from '@/utils/create-app-tracking'
|
||||
@ -54,6 +55,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
|
||||
const { plan, enableBilling } = useProviderContext()
|
||||
const isAppsFull = (enableBilling && plan.usage.buildApps >= plan.total.buildApps)
|
||||
const { isCurrentWorkspaceEditor } = useAppContext()
|
||||
const invalidateAppList = useInvalidateAppList()
|
||||
|
||||
const isCreatingRef = useRef(false)
|
||||
|
||||
@ -85,13 +87,14 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
|
||||
onSuccess()
|
||||
onClose()
|
||||
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
|
||||
invalidateAppList()
|
||||
getRedirection(isCurrentWorkspaceEditor, app, push)
|
||||
}
|
||||
catch (error) {
|
||||
toast.error(error instanceof Error ? error.message : t('newApp.appCreateFailed', { ns: 'app' }))
|
||||
}
|
||||
isCreatingRef.current = false
|
||||
}, [name, t, appMode, appIcon, description, onSuccess, onClose, push, isCurrentWorkspaceEditor])
|
||||
}, [name, t, appMode, appIcon, description, onSuccess, onClose, push, isCurrentWorkspaceEditor, invalidateAppList])
|
||||
|
||||
const { run: handleCreateApp } = useDebounceFn(onCreate, { wait: 300 })
|
||||
useKeyPress(['meta.enter', 'ctrl.enter'], () => {
|
||||
|
||||
@ -11,6 +11,7 @@ const mockImportDSLConfirm = vi.fn()
|
||||
const mockTrackCreateApp = vi.fn()
|
||||
const mockHandleCheckPluginDependencies = vi.fn()
|
||||
const mockGetRedirection = vi.fn()
|
||||
const mockInvalidateAppList = vi.hoisted(() => vi.fn())
|
||||
const toastMocks = vi.hoisted(() => ({
|
||||
call: vi.fn(),
|
||||
success: vi.fn(),
|
||||
@ -52,6 +53,9 @@ vi.mock('@/service/apps', () => ({
|
||||
importDSL: (...args: unknown[]) => mockImportDSL(...args),
|
||||
importDSLConfirm: (...args: unknown[]) => mockImportDSLConfirm(...args),
|
||||
}))
|
||||
vi.mock('@/service/use-apps', () => ({
|
||||
useInvalidateAppList: () => mockInvalidateAppList,
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/workflow/plugin-dependency/hooks', () => ({
|
||||
usePluginDependencies: () => ({
|
||||
@ -201,6 +205,7 @@ describe('CreateFromDSLModal', () => {
|
||||
expect(handleSuccess).toHaveBeenCalledTimes(1)
|
||||
expect(handleClose).toHaveBeenCalledTimes(1)
|
||||
expect(localStorage.getItem(NEED_REFRESH_APP_LIST_KEY)).toBe('1')
|
||||
expect(mockInvalidateAppList).toHaveBeenCalledTimes(1)
|
||||
expect(mockHandleCheckPluginDependencies).toHaveBeenCalledWith('app-1')
|
||||
expect(mockGetRedirection).toHaveBeenCalledWith(true, { id: 'app-1', mode: 'chat' }, mockPush)
|
||||
})
|
||||
@ -305,6 +310,7 @@ describe('CreateFromDSLModal', () => {
|
||||
import_id: 'import-3',
|
||||
})
|
||||
expect(mockTrackCreateApp).toHaveBeenCalledWith({ appMode: AppModeEnum.WORKFLOW })
|
||||
expect(mockInvalidateAppList).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should close the DSL mismatch modal when dialog requests close', async () => {
|
||||
|
||||
@ -23,6 +23,7 @@ import {
|
||||
importDSL,
|
||||
importDSLConfirm,
|
||||
} from '@/service/apps'
|
||||
import { useInvalidateAppList } from '@/service/use-apps'
|
||||
import { getRedirection } from '@/utils/app-redirection'
|
||||
import { trackCreateApp } from '@/utils/create-app-tracking'
|
||||
import ShortcutsName from '../../workflow/shortcuts-name'
|
||||
@ -74,6 +75,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
|
||||
const { isCurrentWorkspaceEditor } = useAppContext()
|
||||
const { plan, enableBilling } = useProviderContext()
|
||||
const isAppsFull = (enableBilling && plan.usage.buildApps >= plan.total.buildApps)
|
||||
const invalidateAppList = useInvalidateAppList()
|
||||
|
||||
const isCreatingRef = useRef(false)
|
||||
|
||||
@ -124,6 +126,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
|
||||
: undefined,
|
||||
})
|
||||
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
|
||||
invalidateAppList()
|
||||
if (app_id)
|
||||
await handleCheckPluginDependencies(app_id)
|
||||
getRedirection(isCurrentWorkspaceEditor, { id: app_id!, mode: app_mode }, push)
|
||||
@ -181,6 +184,7 @@ const CreateFromDSLModal = ({ show, onSuccess, onClose, activeTab = CreateFromDS
|
||||
if (app_id)
|
||||
await handleCheckPluginDependencies(app_id)
|
||||
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
|
||||
invalidateAppList()
|
||||
getRedirection(isCurrentWorkspaceEditor, { id: app_id!, mode: app_mode }, push)
|
||||
}
|
||||
else if (status === DSLImportStatus.FAILED) {
|
||||
|
||||
@ -19,6 +19,7 @@ import {
|
||||
importDSL,
|
||||
importDSLConfirm,
|
||||
} from '@/service/apps'
|
||||
import { useInvalidateAppList } from '@/service/use-apps'
|
||||
import { getRedirection } from '@/utils/app-redirection'
|
||||
|
||||
type DSLPayload = {
|
||||
@ -42,6 +43,7 @@ export const useImportDSL = () => {
|
||||
const { handleCheckPluginDependencies } = usePluginDependencies()
|
||||
const isCurrentWorkspaceEditor = useSelector(s => s.isCurrentWorkspaceEditor)
|
||||
const { push } = useRouter()
|
||||
const invalidateAppList = useInvalidateAppList()
|
||||
const [versions, setVersions] = useState<{ importedVersion: string, systemVersion: string }>()
|
||||
const importIdRef = useRef<string>('')
|
||||
|
||||
@ -87,6 +89,7 @@ export const useImportDSL = () => {
|
||||
toast.warning(message, { description })
|
||||
onSuccess?.()
|
||||
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
|
||||
invalidateAppList()
|
||||
await handleCheckPluginDependencies(app_id)
|
||||
getRedirection(isCurrentWorkspaceEditor, { id: app_id, mode: app_mode }, push)
|
||||
}
|
||||
@ -110,7 +113,7 @@ export const useImportDSL = () => {
|
||||
finally {
|
||||
setIsFetching(false)
|
||||
}
|
||||
}, [t, handleCheckPluginDependencies, isCurrentWorkspaceEditor, push, isFetching])
|
||||
}, [t, handleCheckPluginDependencies, isCurrentWorkspaceEditor, push, isFetching, invalidateAppList])
|
||||
|
||||
const handleImportDSLConfirm = useCallback(async (
|
||||
{
|
||||
@ -138,6 +141,7 @@ export const useImportDSL = () => {
|
||||
toast.success(t('newApp.appCreated', { ns: 'app' }))
|
||||
await handleCheckPluginDependencies(app_id)
|
||||
localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
|
||||
invalidateAppList()
|
||||
getRedirection(isCurrentWorkspaceEditor, { id: app_id!, mode: app_mode }, push)
|
||||
}
|
||||
else if (status === DSLImportStatus.FAILED) {
|
||||
@ -152,7 +156,7 @@ export const useImportDSL = () => {
|
||||
finally {
|
||||
setIsFetching(false)
|
||||
}
|
||||
}, [t, handleCheckPluginDependencies, isCurrentWorkspaceEditor, push, isFetching])
|
||||
}, [t, handleCheckPluginDependencies, isCurrentWorkspaceEditor, push, isFetching, invalidateAppList])
|
||||
|
||||
return {
|
||||
handleImportDSL,
|
||||
|
||||
Reference in New Issue
Block a user