| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- import {
- memo,
- useCallback,
- useEffect,
- useState,
- } from 'react'
- import { useTranslation } from 'react-i18next'
- import {
- COMMAND_PRIORITY_EDITOR,
- } from 'lexical'
- import { mergeRegister } from '@lexical/utils'
- import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
- import { useReactFlow, useStoreApi } from 'reactflow'
- import { useSelectOrDelete } from '../../hooks'
- import type { WorkflowNodesMap } from './node'
- import { WorkflowVariableBlockNode } from './node'
- import {
- DELETE_WORKFLOW_VARIABLE_BLOCK_COMMAND,
- UPDATE_WORKFLOW_NODES_MAP,
- } from './index'
- import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils'
- import Tooltip from '@/app/components/base/tooltip'
- import { isExceptionVariable } from '@/app/components/workflow/utils'
- import VarFullPathPanel from '@/app/components/workflow/nodes/_base/components/variable/var-full-path-panel'
- import { Type } from '@/app/components/workflow/nodes/llm/types'
- import type { ValueSelector, Var } from '@/app/components/workflow/types'
- import {
- VariableLabelInEditor,
- } from '@/app/components/workflow/nodes/_base/components/variable/variable-label'
- type WorkflowVariableBlockComponentProps = {
- nodeKey: string
- variables: string[]
- workflowNodesMap: WorkflowNodesMap
- environmentVariables?: Var[]
- conversationVariables?: Var[]
- getVarType?: (payload: {
- nodeId: string,
- valueSelector: ValueSelector,
- }) => Type
- }
- const WorkflowVariableBlockComponent = ({
- nodeKey,
- variables,
- workflowNodesMap = {},
- getVarType,
- environmentVariables,
- conversationVariables,
- }: WorkflowVariableBlockComponentProps) => {
- const { t } = useTranslation()
- const [editor] = useLexicalComposerContext()
- const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_WORKFLOW_VARIABLE_BLOCK_COMMAND)
- const variablesLength = variables.length
- const isShowAPart = variablesLength > 2
- const varName = (
- () => {
- const isSystem = isSystemVar(variables)
- const varName = variables[variablesLength - 1]
- return `${isSystem ? 'sys.' : ''}${varName}`
- }
- )()
- const [localWorkflowNodesMap, setLocalWorkflowNodesMap] = useState<WorkflowNodesMap>(workflowNodesMap)
- const node = localWorkflowNodesMap![variables[0]]
- const isEnv = isENV(variables)
- const isChatVar = isConversationVar(variables)
- const isException = isExceptionVariable(varName, node?.type)
- let variableValid = true
- if (isEnv) {
- if (environmentVariables)
- variableValid = environmentVariables.some(v => v.variable === `${variables?.[0] ?? ''}.${variables?.[1] ?? ''}`)
- }
- else if (isChatVar) {
- if (conversationVariables)
- variableValid = conversationVariables.some(v => v.variable === `${variables?.[0] ?? ''}.${variables?.[1] ?? ''}`)
- }
- else {
- variableValid = !!node
- }
- const reactflow = useReactFlow()
- const store = useStoreApi()
- useEffect(() => {
- if (!editor.hasNodes([WorkflowVariableBlockNode]))
- throw new Error('WorkflowVariableBlockPlugin: WorkflowVariableBlock not registered on editor')
- return mergeRegister(
- editor.registerCommand(
- UPDATE_WORKFLOW_NODES_MAP,
- (workflowNodesMap: WorkflowNodesMap) => {
- setLocalWorkflowNodesMap(workflowNodesMap)
- return true
- },
- COMMAND_PRIORITY_EDITOR,
- ),
- )
- }, [editor])
- const handleVariableJump = useCallback(() => {
- const workflowContainer = document.getElementById('workflow-container')
- const {
- clientWidth,
- clientHeight,
- } = workflowContainer!
- const {
- setViewport,
- } = reactflow
- const { transform } = store.getState()
- const zoom = transform[2]
- const position = node.position
- setViewport({
- x: (clientWidth - 400 - node.width! * zoom) / 2 - position!.x * zoom,
- y: (clientHeight - node.height! * zoom) / 2 - position!.y * zoom,
- zoom: transform[2],
- })
- }, [node, reactflow, store])
- const Item = (
- <VariableLabelInEditor
- nodeType={node?.type}
- nodeTitle={node?.title}
- variables={variables}
- onClick={(e) => {
- e.stopPropagation()
- handleVariableJump()
- }}
- isExceptionVariable={isException}
- errorMsg={!variableValid ? t('workflow.errorMsg.invalidVariable') : undefined}
- isSelected={isSelected}
- ref={ref}
- notShowFullPath={isShowAPart}
- />
- )
- if (!node)
- return Item
- return (
- <Tooltip
- noDecoration
- popupContent={
- <VarFullPathPanel
- nodeName={node.title}
- path={variables.slice(1)}
- varType={getVarType ? getVarType({
- nodeId: variables[0],
- valueSelector: variables,
- }) : Type.string}
- nodeType={node?.type}
- />}
- disabled={!isShowAPart}
- >
- <div>{Item}</div>
- </Tooltip>
- )
- }
- export default memo(WorkflowVariableBlockComponent)
|