mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 01:48:04 +08:00
refactor: migrate appDetail from Zustand to TanStack Query
- Remove appDetail and setAppDetail from Zustand store - Use useAppDetail hook for server state management - Child components now call useAppDetail(appId) directly via useParams() - Replace setAppDetail calls with useInvalidateAppDetail for cache invalidation - Keep only client UI state in Zustand (sidebar, modals) - Split sidebar initialization useEffect for clearer separation of concerns - Update test mocks to use TanStack Query pattern - Fix missing dependencies in use-checklist.ts useMemo/useCallback hooks
This commit is contained in:
@ -1,15 +1,15 @@
|
||||
import { produce } from 'immer'
|
||||
import { useParams } from 'next/navigation'
|
||||
import { useCallback } from 'react'
|
||||
import { useStoreApi } from 'reactflow'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import { fetchWebhookUrl } from '@/service/apps'
|
||||
|
||||
export const useAutoGenerateWebhookUrl = () => {
|
||||
const reactFlowStore = useStoreApi()
|
||||
const { appId } = useParams()
|
||||
|
||||
return useCallback(async (nodeId: string) => {
|
||||
const appId = useAppStore.getState().appDetail?.id
|
||||
if (!appId)
|
||||
return
|
||||
|
||||
@ -22,7 +22,7 @@ export const useAutoGenerateWebhookUrl = () => {
|
||||
return
|
||||
|
||||
try {
|
||||
const response = await fetchWebhookUrl({ appId, nodeId })
|
||||
const response = await fetchWebhookUrl({ appId: appId as string, nodeId })
|
||||
const { getNodes: getLatestNodes, setNodes } = reactFlowStore.getState()
|
||||
let hasUpdated = false
|
||||
const updatedNodes = produce(getLatestNodes(), (draft) => {
|
||||
@ -44,5 +44,5 @@ export const useAutoGenerateWebhookUrl = () => {
|
||||
catch (error: unknown) {
|
||||
console.error('Failed to auto-generate webhook URL:', error)
|
||||
}
|
||||
}, [reactFlowStore])
|
||||
}, [reactFlowStore, appId])
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import type {
|
||||
import type { Emoji } from '@/app/components/tools/types'
|
||||
import type { DataSet } from '@/models/datasets'
|
||||
import type { I18nKeysWithPrefix } from '@/types/i18n'
|
||||
import { useParams } from 'next/navigation'
|
||||
import {
|
||||
useCallback,
|
||||
useMemo,
|
||||
@ -21,7 +22,6 @@ import {
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useEdges, useStoreApi } from 'reactflow'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { useToastContext } from '@/app/components/base/toast'
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
@ -29,6 +29,7 @@ import useNodes from '@/app/components/workflow/store/workflow/use-nodes'
|
||||
import { MAX_TREE_DEPTH } from '@/config'
|
||||
import { useGetLanguage } from '@/context/i18n'
|
||||
import { fetchDatasets } from '@/service/datasets'
|
||||
import { useAppDetail } from '@/service/use-apps'
|
||||
import { useStrategyProviders } from '@/service/use-strategy'
|
||||
import {
|
||||
useAllBuiltInTools,
|
||||
@ -96,7 +97,9 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
|
||||
const { data: triggerPlugins } = useAllTriggerPlugins()
|
||||
const datasetsDetail = useDatasetsDetailStore(s => s.datasetsDetail)
|
||||
const getToolIcon = useGetToolIcon()
|
||||
const appMode = useAppStore.getState().appDetail?.mode
|
||||
const { appId } = useParams()
|
||||
const { data: appDetail } = useAppDetail(appId as string)
|
||||
const appMode = appDetail?.mode
|
||||
const shouldCheckStartNode = appMode === AppModeEnum.WORKFLOW || appMode === AppModeEnum.ADVANCED_CHAT
|
||||
|
||||
const map = useNodesAvailableVarList(nodes)
|
||||
@ -249,7 +252,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
|
||||
})
|
||||
|
||||
return list
|
||||
}, [nodes, nodesExtraData, edges, buildInTools, customTools, workflowTools, language, dataSourceList, getToolIcon, strategyProviders, getCheckData, t, map, shouldCheckStartNode])
|
||||
}, [nodes, nodesExtraData, edges, buildInTools, customTools, workflowTools, language, dataSourceList, getToolIcon, strategyProviders, triggerPlugins, getCheckData, t, map, shouldCheckStartNode])
|
||||
|
||||
return needWarningNodes
|
||||
}
|
||||
@ -270,7 +273,9 @@ export const useChecklistBeforePublish = () => {
|
||||
const { data: buildInTools } = useAllBuiltInTools()
|
||||
const { data: customTools } = useAllCustomTools()
|
||||
const { data: workflowTools } = useAllWorkflowTools()
|
||||
const appMode = useAppStore.getState().appDetail?.mode
|
||||
const { appId } = useParams()
|
||||
const { data: appDetail } = useAppDetail(appId as string)
|
||||
const appMode = appDetail?.mode
|
||||
const shouldCheckStartNode = appMode === AppModeEnum.WORKFLOW || appMode === AppModeEnum.ADVANCED_CHAT
|
||||
|
||||
const getCheckData = useCallback((data: CommonNodeType<{}>, datasets: DataSet[]) => {
|
||||
@ -419,7 +424,7 @@ export const useChecklistBeforePublish = () => {
|
||||
}
|
||||
|
||||
return true
|
||||
}, [store, notify, t, language, nodesExtraData, strategyProviders, updateDatasetsDetail, getCheckData, workflowStore, buildInTools, customTools, workflowTools, shouldCheckStartNode])
|
||||
}, [store, notify, t, language, nodesExtraData, strategyProviders, updateDatasetsDetail, getCheckData, workflowStore, buildInTools, customTools, workflowTools, shouldCheckStartNode, getNodesAvailableVarList])
|
||||
|
||||
return {
|
||||
handleCheckBeforePublish,
|
||||
|
||||
@ -10,6 +10,7 @@ import type {
|
||||
ValueSelector,
|
||||
} from '../types'
|
||||
import { uniqBy } from 'es-toolkit/compat'
|
||||
import { useParams } from 'next/navigation'
|
||||
import {
|
||||
useCallback,
|
||||
} from 'react'
|
||||
@ -18,9 +19,9 @@ import {
|
||||
getOutgoers,
|
||||
useStoreApi,
|
||||
} from 'reactflow'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { CUSTOM_ITERATION_START_NODE } from '@/app/components/workflow/nodes/iteration-start/constants'
|
||||
import { CUSTOM_LOOP_START_NODE } from '@/app/components/workflow/nodes/loop-start/constants'
|
||||
import { useAppDetail } from '@/service/use-apps'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
import { useNodesMetaData } from '.'
|
||||
import {
|
||||
@ -43,7 +44,8 @@ import {
|
||||
import { useAvailableBlocks } from './use-available-blocks'
|
||||
|
||||
export const useIsChatMode = () => {
|
||||
const appDetail = useAppStore(s => s.appDetail)
|
||||
const { appId } = useParams()
|
||||
const { data: appDetail } = useAppDetail(appId as string)
|
||||
|
||||
return appDetail?.mode === AppModeEnum.ADVANCED_CHAT
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user