mirror of
https://github.com/langgenius/dify.git
synced 2026-05-12 15:58:19 +08:00
fix(web): invalidate plugin checkInstalled cache after version updates
This commit is contained in:
parent
0f7ed6f67e
commit
22a4100dd7
@ -15,6 +15,7 @@ type VersionPickerMock = {
|
|||||||
const {
|
const {
|
||||||
mockSetShowUpdatePluginModal,
|
mockSetShowUpdatePluginModal,
|
||||||
mockRefreshModelProviders,
|
mockRefreshModelProviders,
|
||||||
|
mockInvalidateCheckInstalled,
|
||||||
mockInvalidateAllToolProviders,
|
mockInvalidateAllToolProviders,
|
||||||
mockUninstallPlugin,
|
mockUninstallPlugin,
|
||||||
mockFetchReleases,
|
mockFetchReleases,
|
||||||
@ -23,6 +24,7 @@ const {
|
|||||||
return {
|
return {
|
||||||
mockSetShowUpdatePluginModal: vi.fn(),
|
mockSetShowUpdatePluginModal: vi.fn(),
|
||||||
mockRefreshModelProviders: vi.fn(),
|
mockRefreshModelProviders: vi.fn(),
|
||||||
|
mockInvalidateCheckInstalled: vi.fn(),
|
||||||
mockInvalidateAllToolProviders: vi.fn(),
|
mockInvalidateAllToolProviders: vi.fn(),
|
||||||
mockUninstallPlugin: vi.fn(() => Promise.resolve({ success: true })),
|
mockUninstallPlugin: vi.fn(() => Promise.resolve({ success: true })),
|
||||||
mockFetchReleases: vi.fn(() => Promise.resolve([{ tag_name: 'v2.0.0' }])),
|
mockFetchReleases: vi.fn(() => Promise.resolve([{ tag_name: 'v2.0.0' }])),
|
||||||
@ -46,6 +48,10 @@ vi.mock('@/service/plugins', () => ({
|
|||||||
uninstallPlugin: mockUninstallPlugin,
|
uninstallPlugin: mockUninstallPlugin,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/service/use-plugins', () => ({
|
||||||
|
useInvalidateCheckInstalled: () => mockInvalidateCheckInstalled,
|
||||||
|
}))
|
||||||
|
|
||||||
vi.mock('@/service/use-tools', () => ({
|
vi.mock('@/service/use-tools', () => ({
|
||||||
useInvalidateAllToolProviders: () => mockInvalidateAllToolProviders,
|
useInvalidateAllToolProviders: () => mockInvalidateAllToolProviders,
|
||||||
}))
|
}))
|
||||||
@ -178,6 +184,7 @@ describe('usePluginOperations', () => {
|
|||||||
result.current.handleUpdatedFromMarketplace()
|
result.current.handleUpdatedFromMarketplace()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
expect(mockInvalidateCheckInstalled).toHaveBeenCalled()
|
||||||
expect(mockOnUpdate).toHaveBeenCalled()
|
expect(mockOnUpdate).toHaveBeenCalled()
|
||||||
expect(modalStates.hideUpdateModal).toHaveBeenCalled()
|
expect(modalStates.hideUpdateModal).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
@ -251,6 +258,32 @@ describe('usePluginOperations', () => {
|
|||||||
expect(mockSetShowUpdatePluginModal).toHaveBeenCalled()
|
expect(mockSetShowUpdatePluginModal).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should invalidate checkInstalled when GitHub update save callback fires', async () => {
|
||||||
|
const detail = createPluginDetail({
|
||||||
|
source: PluginSource.github,
|
||||||
|
meta: { repo: 'owner/repo', version: 'v1.0.0', package: 'pkg' },
|
||||||
|
})
|
||||||
|
const { result } = renderHook(() =>
|
||||||
|
usePluginOperations({
|
||||||
|
detail,
|
||||||
|
modalStates,
|
||||||
|
versionPicker,
|
||||||
|
isFromMarketplace: false,
|
||||||
|
onUpdate: mockOnUpdate,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
await result.current.handleUpdate()
|
||||||
|
})
|
||||||
|
|
||||||
|
const firstCall = mockSetShowUpdatePluginModal.mock.calls.at(0)?.[0]
|
||||||
|
firstCall?.onSaveCallback()
|
||||||
|
|
||||||
|
expect(mockInvalidateCheckInstalled).toHaveBeenCalled()
|
||||||
|
expect(mockOnUpdate).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
it('should not show modal when no releases found', async () => {
|
it('should not show modal when no releases found', async () => {
|
||||||
mockFetchReleases.mockResolvedValueOnce([])
|
mockFetchReleases.mockResolvedValueOnce([])
|
||||||
const detail = createPluginDetail({
|
const detail = createPluginDetail({
|
||||||
@ -388,6 +421,7 @@ describe('usePluginOperations', () => {
|
|||||||
await result.current.handleDelete()
|
await result.current.handleDelete()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
expect(mockInvalidateCheckInstalled).toHaveBeenCalled()
|
||||||
expect(mockOnUpdate).toHaveBeenCalledWith(true)
|
expect(mockOnUpdate).toHaveBeenCalledWith(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import Toast from '@/app/components/base/toast'
|
|||||||
import { useModalContext } from '@/context/modal-context'
|
import { useModalContext } from '@/context/modal-context'
|
||||||
import { useProviderContext } from '@/context/provider-context'
|
import { useProviderContext } from '@/context/provider-context'
|
||||||
import { uninstallPlugin } from '@/service/plugins'
|
import { uninstallPlugin } from '@/service/plugins'
|
||||||
|
import { useInvalidateCheckInstalled } from '@/service/use-plugins'
|
||||||
import { useInvalidateAllToolProviders } from '@/service/use-tools'
|
import { useInvalidateAllToolProviders } from '@/service/use-tools'
|
||||||
import { useGitHubReleases } from '../../../install-plugin/hooks'
|
import { useGitHubReleases } from '../../../install-plugin/hooks'
|
||||||
import { PluginCategoryEnum, PluginSource } from '../../../types'
|
import { PluginCategoryEnum, PluginSource } from '../../../types'
|
||||||
@ -41,10 +42,15 @@ export const usePluginOperations = ({
|
|||||||
const { checkForUpdates, fetchReleases } = useGitHubReleases()
|
const { checkForUpdates, fetchReleases } = useGitHubReleases()
|
||||||
const { setShowUpdatePluginModal } = useModalContext()
|
const { setShowUpdatePluginModal } = useModalContext()
|
||||||
const { refreshModelProviders } = useProviderContext()
|
const { refreshModelProviders } = useProviderContext()
|
||||||
|
const invalidateCheckInstalled = useInvalidateCheckInstalled()
|
||||||
const invalidateAllToolProviders = useInvalidateAllToolProviders()
|
const invalidateAllToolProviders = useInvalidateAllToolProviders()
|
||||||
|
|
||||||
const { id, meta, plugin_id } = detail
|
const { id, meta, plugin_id } = detail
|
||||||
const { author, category, name } = detail.declaration || detail
|
const { author, category, name } = detail.declaration || detail
|
||||||
|
const handlePluginUpdated = useCallback((isDelete?: boolean) => {
|
||||||
|
invalidateCheckInstalled()
|
||||||
|
onUpdate?.(isDelete)
|
||||||
|
}, [invalidateCheckInstalled, onUpdate])
|
||||||
|
|
||||||
const handleUpdate = useCallback(async (isDowngrade?: boolean) => {
|
const handleUpdate = useCallback(async (isDowngrade?: boolean) => {
|
||||||
if (isFromMarketplace) {
|
if (isFromMarketplace) {
|
||||||
@ -73,7 +79,7 @@ export const usePluginOperations = ({
|
|||||||
if (needUpdate) {
|
if (needUpdate) {
|
||||||
setShowUpdatePluginModal({
|
setShowUpdatePluginModal({
|
||||||
onSaveCallback: () => {
|
onSaveCallback: () => {
|
||||||
onUpdate?.()
|
handlePluginUpdated()
|
||||||
},
|
},
|
||||||
payload: {
|
payload: {
|
||||||
type: PluginSource.github,
|
type: PluginSource.github,
|
||||||
@ -99,15 +105,15 @@ export const usePluginOperations = ({
|
|||||||
checkForUpdates,
|
checkForUpdates,
|
||||||
setShowUpdatePluginModal,
|
setShowUpdatePluginModal,
|
||||||
detail,
|
detail,
|
||||||
onUpdate,
|
handlePluginUpdated,
|
||||||
modalStates,
|
modalStates,
|
||||||
versionPicker,
|
versionPicker,
|
||||||
])
|
])
|
||||||
|
|
||||||
const handleUpdatedFromMarketplace = useCallback(() => {
|
const handleUpdatedFromMarketplace = useCallback(() => {
|
||||||
onUpdate?.()
|
handlePluginUpdated()
|
||||||
modalStates.hideUpdateModal()
|
modalStates.hideUpdateModal()
|
||||||
}, [onUpdate, modalStates])
|
}, [handlePluginUpdated, modalStates])
|
||||||
|
|
||||||
const handleDelete = useCallback(async () => {
|
const handleDelete = useCallback(async () => {
|
||||||
modalStates.showDeleting()
|
modalStates.showDeleting()
|
||||||
@ -120,7 +126,7 @@ export const usePluginOperations = ({
|
|||||||
type: 'success',
|
type: 'success',
|
||||||
message: t('action.deleteSuccess', { ns: 'plugin' }),
|
message: t('action.deleteSuccess', { ns: 'plugin' }),
|
||||||
})
|
})
|
||||||
onUpdate?.(true)
|
handlePluginUpdated(true)
|
||||||
|
|
||||||
if (PluginCategoryEnum.model.includes(category))
|
if (PluginCategoryEnum.model.includes(category))
|
||||||
refreshModelProviders()
|
refreshModelProviders()
|
||||||
@ -136,7 +142,7 @@ export const usePluginOperations = ({
|
|||||||
plugin_id,
|
plugin_id,
|
||||||
name,
|
name,
|
||||||
modalStates,
|
modalStates,
|
||||||
onUpdate,
|
handlePluginUpdated,
|
||||||
refreshModelProviders,
|
refreshModelProviders,
|
||||||
invalidateAllToolProviders,
|
invalidateAllToolProviders,
|
||||||
])
|
])
|
||||||
|
|||||||
@ -47,6 +47,7 @@ import { useInvalidateAllBuiltInTools } from './use-tools'
|
|||||||
const NAME_SPACE = 'plugins'
|
const NAME_SPACE = 'plugins'
|
||||||
|
|
||||||
const useInstalledPluginListKey = [NAME_SPACE, 'installedPluginList']
|
const useInstalledPluginListKey = [NAME_SPACE, 'installedPluginList']
|
||||||
|
const useCheckInstalledKey = [NAME_SPACE, 'checkInstalled'] as const
|
||||||
export const useCheckInstalled = ({
|
export const useCheckInstalled = ({
|
||||||
pluginIds,
|
pluginIds,
|
||||||
enabled,
|
enabled,
|
||||||
@ -55,7 +56,7 @@ export const useCheckInstalled = ({
|
|||||||
enabled: boolean
|
enabled: boolean
|
||||||
}) => {
|
}) => {
|
||||||
return useQuery<{ plugins: PluginDetail[] }>({
|
return useQuery<{ plugins: PluginDetail[] }>({
|
||||||
queryKey: [NAME_SPACE, 'checkInstalled', pluginIds],
|
queryKey: [...useCheckInstalledKey, pluginIds],
|
||||||
queryFn: () => post<{ plugins: PluginDetail[] }>('/workspaces/current/plugin/list/installations/ids', {
|
queryFn: () => post<{ plugins: PluginDetail[] }>('/workspaces/current/plugin/list/installations/ids', {
|
||||||
body: {
|
body: {
|
||||||
plugin_ids: pluginIds,
|
plugin_ids: pluginIds,
|
||||||
@ -66,6 +67,17 @@ export const useCheckInstalled = ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useInvalidateCheckInstalled = () => {
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
return () => {
|
||||||
|
queryClient.invalidateQueries(
|
||||||
|
{
|
||||||
|
queryKey: useCheckInstalledKey,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const useRecommendedMarketplacePluginsKey = [NAME_SPACE, 'recommendedMarketplacePlugins']
|
const useRecommendedMarketplacePluginsKey = [NAME_SPACE, 'recommendedMarketplacePlugins']
|
||||||
export const useRecommendedMarketplacePlugins = ({
|
export const useRecommendedMarketplacePlugins = ({
|
||||||
collection = '__recommended-plugins-tools',
|
collection = '__recommended-plugins-tools',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user