mirror of
http://112.124.100.131/huang.ze/ebiz-dify-ai.git
synced 2025-12-10 11:26:52 +08:00
Feat/environment variables in workflow (#6515)
Co-authored-by: JzoNg <jzongcode@gmail.com>
This commit is contained in:
@@ -14,3 +14,4 @@ export * from './use-panel-interactions'
|
||||
export * from './use-workflow-start-run'
|
||||
export * from './use-nodes-layout'
|
||||
export * from './use-workflow-history'
|
||||
export * from './use-workflow-variables'
|
||||
|
||||
@@ -31,6 +31,7 @@ export const useNodesSyncDraft = () => {
|
||||
const [x, y, zoom] = transform
|
||||
const {
|
||||
appId,
|
||||
environmentVariables,
|
||||
syncWorkflowDraftHash,
|
||||
} = workflowStore.getState()
|
||||
|
||||
@@ -80,6 +81,7 @@ export const useNodesSyncDraft = () => {
|
||||
sensitive_word_avoidance: features.moderation,
|
||||
file_upload: features.file,
|
||||
},
|
||||
environment_variables: environmentVariables,
|
||||
hash: syncWorkflowDraftHash,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useReactFlow } from 'reactflow'
|
||||
import { useWorkflowStore } from '../store'
|
||||
import { WORKFLOW_DATA_UPDATE } from '../constants'
|
||||
import { DSL_EXPORT_CHECK, WORKFLOW_DATA_UPDATE } from '../constants'
|
||||
import type { WorkflowDataUpdator } from '../types'
|
||||
import {
|
||||
initialEdges,
|
||||
@@ -66,11 +66,18 @@ export const useWorkflowUpdate = () => {
|
||||
appId,
|
||||
setSyncWorkflowDraftHash,
|
||||
setIsSyncingWorkflowDraft,
|
||||
setEnvironmentVariables,
|
||||
setEnvSecrets,
|
||||
} = workflowStore.getState()
|
||||
setIsSyncingWorkflowDraft(true)
|
||||
fetchWorkflowDraft(`/apps/${appId}/workflows/draft`).then((response) => {
|
||||
handleUpdateWorkflowCanvas(response.graph as WorkflowDataUpdator)
|
||||
setSyncWorkflowDraftHash(response.hash)
|
||||
setEnvSecrets((response.environment_variables || []).filter(env => env.value_type === 'secret').reduce((acc, env) => {
|
||||
acc[env.id] = env.value
|
||||
return acc
|
||||
}, {} as Record<string, string>))
|
||||
setEnvironmentVariables(response.environment_variables?.map(env => env.value_type === 'secret' ? { ...env, value: '[__HIDDEN__]' } : env) || [])
|
||||
}).finally(() => setIsSyncingWorkflowDraft(false))
|
||||
}, [handleUpdateWorkflowCanvas, workflowStore])
|
||||
|
||||
@@ -83,12 +90,13 @@ export const useWorkflowUpdate = () => {
|
||||
export const useDSL = () => {
|
||||
const { t } = useTranslation()
|
||||
const { notify } = useToastContext()
|
||||
const { eventEmitter } = useEventEmitterContextContext()
|
||||
const [exporting, setExporting] = useState(false)
|
||||
const { doSyncWorkflowDraft } = useNodesSyncDraft()
|
||||
|
||||
const appDetail = useAppStore(s => s.appDetail)
|
||||
|
||||
const handleExportDSL = useCallback(async () => {
|
||||
const handleExportDSL = useCallback(async (include = false) => {
|
||||
if (!appDetail)
|
||||
return
|
||||
|
||||
@@ -98,7 +106,10 @@ export const useDSL = () => {
|
||||
try {
|
||||
setExporting(true)
|
||||
await doSyncWorkflowDraft()
|
||||
const { data } = await exportAppConfig(appDetail.id)
|
||||
const { data } = await exportAppConfig({
|
||||
appID: appDetail.id,
|
||||
include,
|
||||
})
|
||||
const a = document.createElement('a')
|
||||
const file = new Blob([data], { type: 'application/yaml' })
|
||||
a.href = URL.createObjectURL(file)
|
||||
@@ -113,7 +124,30 @@ export const useDSL = () => {
|
||||
}
|
||||
}, [appDetail, notify, t, doSyncWorkflowDraft, exporting])
|
||||
|
||||
const exportCheck = useCallback(async () => {
|
||||
if (!appDetail)
|
||||
return
|
||||
try {
|
||||
const workflowDraft = await fetchWorkflowDraft(`/apps/${appDetail?.id}/workflows/draft`)
|
||||
const list = (workflowDraft.environment_variables || []).filter(env => env.value_type === 'secret')
|
||||
if (list.length === 0) {
|
||||
handleExportDSL()
|
||||
return
|
||||
}
|
||||
eventEmitter?.emit({
|
||||
type: DSL_EXPORT_CHECK,
|
||||
payload: {
|
||||
data: list,
|
||||
},
|
||||
} as any)
|
||||
}
|
||||
catch (e) {
|
||||
notify({ type: 'error', message: t('app.exportFailed') })
|
||||
}
|
||||
}, [appDetail, eventEmitter, handleExportDSL, notify, t])
|
||||
|
||||
return {
|
||||
exportCheck,
|
||||
handleExportDSL,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ export const useWorkflowRun = () => {
|
||||
const {
|
||||
backupDraft,
|
||||
setBackupDraft,
|
||||
environmentVariables,
|
||||
} = workflowStore.getState()
|
||||
const { features } = featuresStore!.getState()
|
||||
|
||||
@@ -50,6 +51,7 @@ export const useWorkflowRun = () => {
|
||||
edges,
|
||||
viewport: getViewport(),
|
||||
features,
|
||||
environmentVariables,
|
||||
})
|
||||
doSyncWorkflowDraft()
|
||||
}
|
||||
@@ -59,6 +61,7 @@ export const useWorkflowRun = () => {
|
||||
const {
|
||||
backupDraft,
|
||||
setBackupDraft,
|
||||
setEnvironmentVariables,
|
||||
} = workflowStore.getState()
|
||||
|
||||
if (backupDraft) {
|
||||
@@ -67,12 +70,14 @@ export const useWorkflowRun = () => {
|
||||
edges,
|
||||
viewport,
|
||||
features,
|
||||
environmentVariables,
|
||||
} = backupDraft
|
||||
handleUpdateWorkflowCanvas({
|
||||
nodes,
|
||||
edges,
|
||||
viewport,
|
||||
})
|
||||
setEnvironmentVariables(environmentVariables)
|
||||
featuresStore!.setState({ features })
|
||||
setBackupDraft(undefined)
|
||||
}
|
||||
@@ -522,6 +527,7 @@ export const useWorkflowRun = () => {
|
||||
})
|
||||
featuresStore?.setState({ features: publishedWorkflow.features })
|
||||
workflowStore.getState().setPublishedAt(publishedWorkflow.created_at)
|
||||
workflowStore.getState().setEnvironmentVariables(publishedWorkflow.environment_variables || [])
|
||||
}
|
||||
}, [featuresStore, handleUpdateWorkflowCanvas, workflowStore])
|
||||
|
||||
|
||||
@@ -39,8 +39,11 @@ export const useWorkflowStartRun = () => {
|
||||
showDebugAndPreviewPanel,
|
||||
setShowDebugAndPreviewPanel,
|
||||
setShowInputsPanel,
|
||||
setShowEnvPanel,
|
||||
} = workflowStore.getState()
|
||||
|
||||
setShowEnvPanel(false)
|
||||
|
||||
if (showDebugAndPreviewPanel) {
|
||||
handleCancelDebugAndPreviewPanel()
|
||||
return
|
||||
@@ -63,8 +66,11 @@ export const useWorkflowStartRun = () => {
|
||||
showDebugAndPreviewPanel,
|
||||
setShowDebugAndPreviewPanel,
|
||||
setHistoryWorkflowData,
|
||||
setShowEnvPanel,
|
||||
} = workflowStore.getState()
|
||||
|
||||
setShowEnvPanel(false)
|
||||
|
||||
if (showDebugAndPreviewPanel)
|
||||
handleCancelDebugAndPreviewPanel()
|
||||
else
|
||||
|
||||
69
web/app/components/workflow/hooks/use-workflow-variables.ts
Normal file
69
web/app/components/workflow/hooks/use-workflow-variables.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useStore } from '../store'
|
||||
import { getVarType, toNodeAvailableVars } from '@/app/components/workflow/nodes/_base/components/variable/utils'
|
||||
import type {
|
||||
Node,
|
||||
NodeOutPutVar,
|
||||
ValueSelector,
|
||||
Var,
|
||||
} from '@/app/components/workflow/types'
|
||||
|
||||
export const useWorkflowVariables = () => {
|
||||
const { t } = useTranslation()
|
||||
const environmentVariables = useStore(s => s.environmentVariables)
|
||||
|
||||
const getNodeAvailableVars = useCallback(({
|
||||
parentNode,
|
||||
beforeNodes,
|
||||
isChatMode,
|
||||
filterVar,
|
||||
hideEnv,
|
||||
}: {
|
||||
parentNode?: Node | null
|
||||
beforeNodes: Node[]
|
||||
isChatMode: boolean
|
||||
filterVar: (payload: Var, selector: ValueSelector) => boolean
|
||||
hideEnv?: boolean
|
||||
}): NodeOutPutVar[] => {
|
||||
return toNodeAvailableVars({
|
||||
parentNode,
|
||||
t,
|
||||
beforeNodes,
|
||||
isChatMode,
|
||||
environmentVariables: hideEnv ? [] : environmentVariables,
|
||||
filterVar,
|
||||
})
|
||||
}, [environmentVariables, t])
|
||||
|
||||
const getCurrentVariableType = useCallback(({
|
||||
parentNode,
|
||||
valueSelector,
|
||||
isIterationItem,
|
||||
availableNodes,
|
||||
isChatMode,
|
||||
isConstant,
|
||||
}: {
|
||||
valueSelector: ValueSelector
|
||||
parentNode?: Node | null
|
||||
isIterationItem?: boolean
|
||||
availableNodes: any[]
|
||||
isChatMode: boolean
|
||||
isConstant?: boolean
|
||||
}) => {
|
||||
return getVarType({
|
||||
parentNode,
|
||||
valueSelector,
|
||||
isIterationItem,
|
||||
availableNodes,
|
||||
isChatMode,
|
||||
isConstant,
|
||||
environmentVariables,
|
||||
})
|
||||
}, [environmentVariables])
|
||||
|
||||
return {
|
||||
getNodeAvailableVars,
|
||||
getCurrentVariableType,
|
||||
}
|
||||
}
|
||||
@@ -471,8 +471,14 @@ export const useWorkflowInit = () => {
|
||||
const handleGetInitialWorkflowData = useCallback(async () => {
|
||||
try {
|
||||
const res = await fetchWorkflowDraft(`/apps/${appDetail.id}/workflows/draft`)
|
||||
|
||||
setData(res)
|
||||
workflowStore.setState({
|
||||
envSecrets: (res.environment_variables || []).filter(env => env.value_type === 'secret').reduce((acc, env) => {
|
||||
acc[env.id] = env.value
|
||||
return acc
|
||||
}, {} as Record<string, string>),
|
||||
environmentVariables: res.environment_variables?.map(env => env.value_type === 'secret' ? { ...env, value: '[__HIDDEN__]' } : env) || [],
|
||||
})
|
||||
setSyncWorkflowDraftHash(res.hash)
|
||||
setIsLoading(false)
|
||||
}
|
||||
@@ -491,6 +497,7 @@ export const useWorkflowInit = () => {
|
||||
features: {
|
||||
retriever_resource: { enabled: true },
|
||||
},
|
||||
environment_variables: [],
|
||||
},
|
||||
}).then((res) => {
|
||||
workflowStore.getState().setDraftUpdatedAt(res.updated_at)
|
||||
|
||||
Reference in New Issue
Block a user