mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
refactor(web): replace query hooks with queryOptions factories (#32520)
This commit is contained in:
@ -8,12 +8,22 @@ import {
|
||||
useSkillAssetTreeData,
|
||||
} from './use-skill-asset-tree'
|
||||
|
||||
const { mockUseGetAppAssetTree } = vi.hoisted(() => ({
|
||||
mockUseGetAppAssetTree: vi.fn(),
|
||||
const { mockUseQuery, mockAppAssetTreeOptions } = vi.hoisted(() => ({
|
||||
mockUseQuery: vi.fn(),
|
||||
mockAppAssetTreeOptions: vi.fn().mockReturnValue({
|
||||
queryKey: ['test', 'tree'],
|
||||
queryFn: vi.fn(),
|
||||
enabled: true,
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@tanstack/react-query', async importOriginal => ({
|
||||
...await importOriginal<typeof import('@tanstack/react-query')>(),
|
||||
useQuery: (options: unknown) => mockUseQuery(options),
|
||||
}))
|
||||
|
||||
vi.mock('@/service/use-app-asset', () => ({
|
||||
useGetAppAssetTree: (...args: unknown[]) => mockUseGetAppAssetTree(...args),
|
||||
appAssetTreeOptions: (...args: unknown[]) => mockAppAssetTreeOptions(...args),
|
||||
}))
|
||||
|
||||
const createTreeNode = (
|
||||
@ -34,22 +44,21 @@ describe('useSkillAssetTree', () => {
|
||||
useAppStore.setState({
|
||||
appDetail: { id: 'app-1' } as App & Partial<AppSSO>,
|
||||
})
|
||||
mockUseGetAppAssetTree.mockReturnValue({
|
||||
mockUseQuery.mockReturnValue({
|
||||
data: null,
|
||||
isPending: false,
|
||||
error: null,
|
||||
})
|
||||
})
|
||||
|
||||
// Scenario: should pass app id from app store to the data query hook.
|
||||
describe('useSkillAssetTreeData', () => {
|
||||
it('should request tree data with current app id', () => {
|
||||
const expectedResult = { data: { children: [] }, isPending: false }
|
||||
mockUseGetAppAssetTree.mockReturnValue(expectedResult)
|
||||
mockUseQuery.mockReturnValue(expectedResult)
|
||||
|
||||
const { result } = renderHook(() => useSkillAssetTreeData())
|
||||
|
||||
expect(mockUseGetAppAssetTree).toHaveBeenCalledWith('app-1')
|
||||
expect(mockAppAssetTreeOptions).toHaveBeenCalledWith('app-1')
|
||||
expect(result.current).toBe(expectedResult)
|
||||
})
|
||||
|
||||
@ -58,16 +67,15 @@ describe('useSkillAssetTree', () => {
|
||||
|
||||
renderHook(() => useSkillAssetTreeData())
|
||||
|
||||
expect(mockUseGetAppAssetTree).toHaveBeenCalledWith('')
|
||||
expect(mockAppAssetTreeOptions).toHaveBeenCalledWith('')
|
||||
})
|
||||
})
|
||||
|
||||
// Scenario: should expose a select transform that builds node lookup maps.
|
||||
describe('useSkillAssetNodeMap', () => {
|
||||
it('should build a map including nested nodes', () => {
|
||||
renderHook(() => useSkillAssetNodeMap())
|
||||
|
||||
const options = mockUseGetAppAssetTree.mock.calls[0][1] as {
|
||||
const options = mockUseQuery.mock.calls[0][0] as {
|
||||
select: (data: AppAssetTreeResponse) => Map<string, AppAssetTreeView>
|
||||
}
|
||||
|
||||
@ -97,7 +105,7 @@ describe('useSkillAssetTree', () => {
|
||||
it('should return an empty map when tree response has no children', () => {
|
||||
renderHook(() => useSkillAssetNodeMap())
|
||||
|
||||
const options = mockUseGetAppAssetTree.mock.calls[0][1] as {
|
||||
const options = mockUseQuery.mock.calls[0][0] as {
|
||||
select: (data: AppAssetTreeResponse) => Map<string, AppAssetTreeView>
|
||||
}
|
||||
|
||||
@ -107,12 +115,11 @@ describe('useSkillAssetTree', () => {
|
||||
})
|
||||
})
|
||||
|
||||
// Scenario: should expose root-level existing skill folder names.
|
||||
describe('useExistingSkillNames', () => {
|
||||
it('should collect only root folder names', () => {
|
||||
renderHook(() => useExistingSkillNames())
|
||||
|
||||
const options = mockUseGetAppAssetTree.mock.calls[0][1] as {
|
||||
const options = mockUseQuery.mock.calls[0][0] as {
|
||||
select: (data: AppAssetTreeResponse) => Set<string>
|
||||
}
|
||||
|
||||
@ -153,7 +160,7 @@ describe('useSkillAssetTree', () => {
|
||||
it('should return an empty set when tree response has no children', () => {
|
||||
renderHook(() => useExistingSkillNames())
|
||||
|
||||
const options = mockUseGetAppAssetTree.mock.calls[0][1] as {
|
||||
const options = mockUseQuery.mock.calls[0][0] as {
|
||||
select: (data: AppAssetTreeResponse) => Set<string>
|
||||
}
|
||||
|
||||
|
||||
@ -1,33 +1,23 @@
|
||||
import type { AppAssetTreeResponse, AppAssetTreeView } from '@/types/app-asset'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { useGetAppAssetTree } from '@/service/use-app-asset'
|
||||
import { appAssetTreeOptions } from '@/service/use-app-asset'
|
||||
import { buildNodeMap } from '../../../utils/tree-utils'
|
||||
|
||||
/**
|
||||
* Get the current app ID from the app store.
|
||||
* Used internally by skill asset tree hooks.
|
||||
*/
|
||||
function useSkillAppId(): string {
|
||||
const appDetail = useAppStore(s => s.appDetail)
|
||||
return appDetail?.id || ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to get the asset tree data for the current skill app.
|
||||
* Returns the raw tree data along with loading and error states.
|
||||
*/
|
||||
export function useSkillAssetTreeData() {
|
||||
const appId = useSkillAppId()
|
||||
return useGetAppAssetTree(appId)
|
||||
return useQuery(appAssetTreeOptions(appId))
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to get the node map (id -> node) for the current skill app.
|
||||
* Uses TanStack Query's select option to compute and cache the map.
|
||||
*/
|
||||
export function useSkillAssetNodeMap() {
|
||||
const appId = useSkillAppId()
|
||||
return useGetAppAssetTree(appId, {
|
||||
return useQuery({
|
||||
...appAssetTreeOptions(appId),
|
||||
select: (data: AppAssetTreeResponse): Map<string, AppAssetTreeView> => {
|
||||
if (!data?.children)
|
||||
return new Map()
|
||||
@ -36,13 +26,10 @@ export function useSkillAssetNodeMap() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to get the set of root-level folder names in the skill asset tree.
|
||||
* Useful for checking whether a skill template has already been added.
|
||||
*/
|
||||
export function useExistingSkillNames() {
|
||||
const appId = useSkillAppId()
|
||||
return useGetAppAssetTree(appId, {
|
||||
return useQuery({
|
||||
...appAssetTreeOptions(appId),
|
||||
select: (data: AppAssetTreeResponse): Set<string> => {
|
||||
if (!data?.children)
|
||||
return new Set()
|
||||
|
||||
Reference in New Issue
Block a user