Fix/workflow use nodes hooks (#21822)
This commit is contained in:
@@ -3,7 +3,7 @@ import {
|
|||||||
useCallback,
|
useCallback,
|
||||||
useMemo,
|
useMemo,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useNodes } from 'reactflow'
|
import { useStore as useReactflowStore } from 'reactflow'
|
||||||
import { RiApps2AddLine } from '@remixicon/react'
|
import { RiApps2AddLine } from '@remixicon/react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import {
|
import {
|
||||||
@@ -22,7 +22,6 @@ import {
|
|||||||
BlockEnum,
|
BlockEnum,
|
||||||
InputVarType,
|
InputVarType,
|
||||||
} from '@/app/components/workflow/types'
|
} from '@/app/components/workflow/types'
|
||||||
import type { StartNodeType } from '@/app/components/workflow/nodes/start/types'
|
|
||||||
import { useToastContext } from '@/app/components/base/toast'
|
import { useToastContext } from '@/app/components/base/toast'
|
||||||
import { usePublishWorkflow, useResetWorkflowVersionHistory } from '@/service/use-workflow'
|
import { usePublishWorkflow, useResetWorkflowVersionHistory } from '@/service/use-workflow'
|
||||||
import type { PublishWorkflowParams } from '@/types/workflow'
|
import type { PublishWorkflowParams } from '@/types/workflow'
|
||||||
@@ -42,9 +41,9 @@ const FeaturesTrigger = () => {
|
|||||||
const publishedAt = useStore(s => s.publishedAt)
|
const publishedAt = useStore(s => s.publishedAt)
|
||||||
const draftUpdatedAt = useStore(s => s.draftUpdatedAt)
|
const draftUpdatedAt = useStore(s => s.draftUpdatedAt)
|
||||||
const toolPublished = useStore(s => s.toolPublished)
|
const toolPublished = useStore(s => s.toolPublished)
|
||||||
const nodes = useNodes<StartNodeType>()
|
const startVariables = useReactflowStore(
|
||||||
const startNode = nodes.find(node => node.data.type === BlockEnum.Start)
|
s => s.getNodes().find(node => node.data.type === BlockEnum.Start)?.data.variables,
|
||||||
const startVariables = startNode?.data.variables
|
)
|
||||||
const fileSettings = useFeatures(s => s.features.file)
|
const fileSettings = useFeatures(s => s.features.file)
|
||||||
const variables = useMemo(() => {
|
const variables = useMemo(() => {
|
||||||
const data = startVariables || []
|
const data = startVariables || []
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import { memo, useMemo } from 'react'
|
import { memo, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { isEqual } from 'lodash-es'
|
||||||
import {
|
import {
|
||||||
getConnectedEdges,
|
getConnectedEdges,
|
||||||
getOutgoers,
|
getOutgoers,
|
||||||
useEdges,
|
useStore,
|
||||||
useStoreApi,
|
|
||||||
} from 'reactflow'
|
} from 'reactflow'
|
||||||
import { useToolIcon } from '../../../../hooks'
|
import { useToolIcon } from '../../../../hooks'
|
||||||
import BlockIcon from '../../../../block-icon'
|
import BlockIcon from '../../../../block-icon'
|
||||||
@@ -26,12 +26,21 @@ const NextStep = ({
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const data = selectedNode.data
|
const data = selectedNode.data
|
||||||
const toolIcon = useToolIcon(data)
|
const toolIcon = useToolIcon(data)
|
||||||
const store = useStoreApi()
|
|
||||||
const branches = useMemo(() => {
|
const branches = useMemo(() => {
|
||||||
return data._targetBranches || []
|
return data._targetBranches || []
|
||||||
}, [data])
|
}, [data])
|
||||||
const edges = useEdges()
|
const edges = useStore(s => s.edges.map(edge => ({
|
||||||
const outgoers = getOutgoers(selectedNode as Node, store.getState().getNodes(), edges)
|
id: edge.id,
|
||||||
|
source: edge.source,
|
||||||
|
sourceHandle: edge.sourceHandle,
|
||||||
|
target: edge.target,
|
||||||
|
targetHandle: edge.targetHandle,
|
||||||
|
})), isEqual)
|
||||||
|
const nodes = useStore(s => s.getNodes().map(node => ({
|
||||||
|
id: node.id,
|
||||||
|
data: node.data,
|
||||||
|
})), isEqual)
|
||||||
|
const outgoers = getOutgoers(selectedNode as Node, nodes as Node[], edges)
|
||||||
const connectedEdges = getConnectedEdges([selectedNode] as Node[], edges).filter(edge => edge.source === selectedNode!.id)
|
const connectedEdges = getConnectedEdges([selectedNode] as Node[], edges).filter(edge => edge.source === selectedNode!.id)
|
||||||
|
|
||||||
const list = useMemo(() => {
|
const list = useMemo(() => {
|
||||||
|
@@ -1,30 +1,39 @@
|
|||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { useShallow } from 'zustand/react/shallow'
|
||||||
import { RiCrosshairLine } from '@remixicon/react'
|
import { RiCrosshairLine } from '@remixicon/react'
|
||||||
import type { XYPosition } from 'reactflow'
|
import { useReactFlow, useStore } from 'reactflow'
|
||||||
import { useReactFlow, useStoreApi } from 'reactflow'
|
|
||||||
import TooltipPlus from '@/app/components/base/tooltip'
|
import TooltipPlus from '@/app/components/base/tooltip'
|
||||||
import { useNodesSyncDraft } from '@/app/components/workflow-app/hooks'
|
import { useNodesSyncDraft } from '@/app/components/workflow-app/hooks'
|
||||||
|
|
||||||
type NodePositionProps = {
|
type NodePositionProps = {
|
||||||
nodePosition: XYPosition,
|
nodeId: string
|
||||||
nodeWidth?: number | null,
|
|
||||||
nodeHeight?: number | null,
|
|
||||||
}
|
}
|
||||||
const NodePosition = ({
|
const NodePosition = ({
|
||||||
nodePosition,
|
nodeId,
|
||||||
nodeWidth,
|
|
||||||
nodeHeight,
|
|
||||||
}: NodePositionProps) => {
|
}: NodePositionProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const reactflow = useReactFlow()
|
const reactflow = useReactFlow()
|
||||||
const store = useStoreApi()
|
|
||||||
const { doSyncWorkflowDraft } = useNodesSyncDraft()
|
const { doSyncWorkflowDraft } = useNodesSyncDraft()
|
||||||
|
const {
|
||||||
|
nodePosition,
|
||||||
|
nodeWidth,
|
||||||
|
nodeHeight,
|
||||||
|
} = useStore(useShallow((s) => {
|
||||||
|
const nodes = s.getNodes()
|
||||||
|
const currentNode = nodes.find(node => node.id === nodeId)!
|
||||||
|
|
||||||
|
return {
|
||||||
|
nodePosition: currentNode.position,
|
||||||
|
nodeWidth: currentNode.width,
|
||||||
|
nodeHeight: currentNode.height,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
const transform = useStore(s => s.transform)
|
||||||
|
|
||||||
if (!nodePosition || !nodeWidth || !nodeHeight) return null
|
if (!nodePosition || !nodeWidth || !nodeHeight) return null
|
||||||
|
|
||||||
const workflowContainer = document.getElementById('workflow-container')
|
const workflowContainer = document.getElementById('workflow-container')
|
||||||
const { transform } = store.getState()
|
|
||||||
const zoom = transform[2]
|
const zoom = transform[2]
|
||||||
|
|
||||||
const { clientWidth, clientHeight } = workflowContainer!
|
const { clientWidth, clientHeight } = workflowContainer!
|
||||||
|
@@ -62,15 +62,14 @@ import { Stop } from '@/app/components/base/icons/src/vender/line/mediaAndDevice
|
|||||||
|
|
||||||
type BasePanelProps = {
|
type BasePanelProps = {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
} & Node
|
id: Node['id']
|
||||||
|
data: Node['data']
|
||||||
|
}
|
||||||
|
|
||||||
const BasePanel: FC<BasePanelProps> = ({
|
const BasePanel: FC<BasePanelProps> = ({
|
||||||
id,
|
id,
|
||||||
data,
|
data,
|
||||||
children,
|
children,
|
||||||
position,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { showMessageLogModal } = useAppStore(useShallow(state => ({
|
const { showMessageLogModal } = useAppStore(useShallow(state => ({
|
||||||
@@ -330,7 +329,7 @@ const BasePanel: FC<BasePanelProps> = ({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<NodePosition nodePosition={position} nodeWidth={width} nodeHeight={height}></NodePosition>
|
<NodePosition nodeId={id}></NodePosition>
|
||||||
<HelpLink nodeType={data.type} />
|
<HelpLink nodeType={data.type} />
|
||||||
<PanelOperator id={id} data={data} showHelpLink={false} />
|
<PanelOperator id={id} data={data} showHelpLink={false} />
|
||||||
<div className='mx-3 h-3.5 w-[1px] bg-divider-regular' />
|
<div className='mx-3 h-3.5 w-[1px] bg-divider-regular' />
|
||||||
|
@@ -48,7 +48,9 @@ import useInspectVarsCrud from '../../hooks/use-inspect-vars-crud'
|
|||||||
|
|
||||||
type BaseNodeProps = {
|
type BaseNodeProps = {
|
||||||
children: ReactElement
|
children: ReactElement
|
||||||
} & NodeProps
|
id: NodeProps['id']
|
||||||
|
data: NodeProps['data']
|
||||||
|
}
|
||||||
|
|
||||||
const BaseNode: FC<BaseNodeProps> = ({
|
const BaseNode: FC<BaseNodeProps> = ({
|
||||||
id,
|
id,
|
||||||
|
@@ -14,11 +14,14 @@ import BasePanel from './_base/components/workflow-panel'
|
|||||||
|
|
||||||
const CustomNode = (props: NodeProps) => {
|
const CustomNode = (props: NodeProps) => {
|
||||||
const nodeData = props.data
|
const nodeData = props.data
|
||||||
const NodeComponent = NodeComponentMap[nodeData.type]
|
const NodeComponent = useMemo(() => NodeComponentMap[nodeData.type], [nodeData.type])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<BaseNode {...props}>
|
<BaseNode
|
||||||
|
id={props.id}
|
||||||
|
data={props.data}
|
||||||
|
>
|
||||||
<NodeComponent />
|
<NodeComponent />
|
||||||
</BaseNode>
|
</BaseNode>
|
||||||
</>
|
</>
|
||||||
@@ -26,7 +29,12 @@ const CustomNode = (props: NodeProps) => {
|
|||||||
}
|
}
|
||||||
CustomNode.displayName = 'CustomNode'
|
CustomNode.displayName = 'CustomNode'
|
||||||
|
|
||||||
export const Panel = memo((props: Node) => {
|
export type PanelProps = {
|
||||||
|
type: Node['type']
|
||||||
|
id: Node['id']
|
||||||
|
data: Node['data']
|
||||||
|
}
|
||||||
|
export const Panel = memo((props: PanelProps) => {
|
||||||
const nodeClass = props.type
|
const nodeClass = props.type
|
||||||
const nodeData = props.data
|
const nodeData = props.data
|
||||||
const PanelComponent = useMemo(() => {
|
const PanelComponent = useMemo(() => {
|
||||||
@@ -38,7 +46,11 @@ export const Panel = memo((props: Node) => {
|
|||||||
|
|
||||||
if (nodeClass === CUSTOM_NODE) {
|
if (nodeClass === CUSTOM_NODE) {
|
||||||
return (
|
return (
|
||||||
<BasePanel key={props.id} {...props}>
|
<BasePanel
|
||||||
|
key={props.id}
|
||||||
|
id={props.id}
|
||||||
|
data={props.data}
|
||||||
|
>
|
||||||
<PanelComponent />
|
<PanelComponent />
|
||||||
</BasePanel>
|
</BasePanel>
|
||||||
)
|
)
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
|
import { useShallow } from 'zustand/react/shallow'
|
||||||
import { memo, useCallback, useEffect, useRef } from 'react'
|
import { memo, useCallback, useEffect, useRef } from 'react'
|
||||||
import { useNodes } from 'reactflow'
|
import { useStore as useReactflow } from 'reactflow'
|
||||||
import type { CommonNodeType } from '../types'
|
|
||||||
import { Panel as NodePanel } from '../nodes'
|
import { Panel as NodePanel } from '../nodes'
|
||||||
import { useStore } from '../store'
|
import { useStore } from '../store'
|
||||||
import EnvPanel from './env-panel'
|
import EnvPanel from './env-panel'
|
||||||
@@ -61,8 +61,18 @@ const useResizeObserver = (
|
|||||||
const Panel: FC<PanelProps> = ({
|
const Panel: FC<PanelProps> = ({
|
||||||
components,
|
components,
|
||||||
}) => {
|
}) => {
|
||||||
const nodes = useNodes<CommonNodeType>()
|
const selectedNode = useReactflow(useShallow((s) => {
|
||||||
const selectedNode = nodes.find(node => node.data.selected)
|
const nodes = s.getNodes()
|
||||||
|
const currentNode = nodes.find(node => node.data.selected)
|
||||||
|
|
||||||
|
if (currentNode) {
|
||||||
|
return {
|
||||||
|
id: currentNode.id,
|
||||||
|
type: currentNode.type,
|
||||||
|
data: currentNode.data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
const showEnvPanel = useStore(s => s.showEnvPanel)
|
const showEnvPanel = useStore(s => s.showEnvPanel)
|
||||||
const isRestoring = useStore(s => s.isRestoring)
|
const isRestoring = useStore(s => s.isRestoring)
|
||||||
const showWorkflowVersionHistoryPanel = useStore(s => s.showWorkflowVersionHistoryPanel)
|
const showWorkflowVersionHistoryPanel = useStore(s => s.showWorkflowVersionHistoryPanel)
|
||||||
|
Reference in New Issue
Block a user