123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- import { useCallback } from 'react'
- import produce from 'immer'
- import { useTranslation } from 'react-i18next'
- import { useStoreApi } from 'reactflow'
- import type {
- BlockEnum,
- Node,
- } from '../../types'
- import { generateNewNode } from '../../utils'
- import {
- LOOP_PADDING,
- NODES_INITIAL_DATA,
- } from '../../constants'
- import { CUSTOM_LOOP_START_NODE } from '../loop-start/constants'
- export const useNodeLoopInteractions = () => {
- const { t } = useTranslation()
- const store = useStoreApi()
- const handleNodeLoopRerender = useCallback((nodeId: string) => {
- const {
- getNodes,
- setNodes,
- } = store.getState()
- const nodes = getNodes()
- const currentNode = nodes.find(n => n.id === nodeId)!
- const childrenNodes = nodes.filter(n => n.parentId === nodeId)
- let rightNode: Node
- let bottomNode: Node
- childrenNodes.forEach((n) => {
- if (rightNode) {
- if (n.position.x + n.width! > rightNode.position.x + rightNode.width!)
- rightNode = n
- }
- else {
- rightNode = n
- }
- if (bottomNode) {
- if (n.position.y + n.height! > bottomNode.position.y + bottomNode.height!)
- bottomNode = n
- }
- else {
- bottomNode = n
- }
- })
- const widthShouldExtend = rightNode! && currentNode.width! < rightNode.position.x + rightNode.width!
- const heightShouldExtend = bottomNode! && currentNode.height! < bottomNode.position.y + bottomNode.height!
- if (widthShouldExtend || heightShouldExtend) {
- const newNodes = produce(nodes, (draft) => {
- draft.forEach((n) => {
- if (n.id === nodeId) {
- if (widthShouldExtend) {
- n.data.width = rightNode.position.x + rightNode.width! + LOOP_PADDING.right
- n.width = rightNode.position.x + rightNode.width! + LOOP_PADDING.right
- }
- if (heightShouldExtend) {
- n.data.height = bottomNode.position.y + bottomNode.height! + LOOP_PADDING.bottom
- n.height = bottomNode.position.y + bottomNode.height! + LOOP_PADDING.bottom
- }
- }
- })
- })
- setNodes(newNodes)
- }
- }, [store])
- const handleNodeLoopChildDrag = useCallback((node: Node) => {
- const { getNodes } = store.getState()
- const nodes = getNodes()
- const restrictPosition: { x?: number; y?: number } = { x: undefined, y: undefined }
- if (node.data.isInLoop) {
- const parentNode = nodes.find(n => n.id === node.parentId)
- if (parentNode) {
- if (node.position.y < LOOP_PADDING.top)
- restrictPosition.y = LOOP_PADDING.top
- if (node.position.x < LOOP_PADDING.left)
- restrictPosition.x = LOOP_PADDING.left
- if (node.position.x + node.width! > parentNode!.width! - LOOP_PADDING.right)
- restrictPosition.x = parentNode!.width! - LOOP_PADDING.right - node.width!
- if (node.position.y + node.height! > parentNode!.height! - LOOP_PADDING.bottom)
- restrictPosition.y = parentNode!.height! - LOOP_PADDING.bottom - node.height!
- }
- }
- return {
- restrictPosition,
- }
- }, [store])
- const handleNodeLoopChildSizeChange = useCallback((nodeId: string) => {
- const { getNodes } = store.getState()
- const nodes = getNodes()
- const currentNode = nodes.find(n => n.id === nodeId)!
- const parentId = currentNode.parentId
- if (parentId)
- handleNodeLoopRerender(parentId)
- }, [store, handleNodeLoopRerender])
- const handleNodeLoopChildrenCopy = useCallback((nodeId: string, newNodeId: string) => {
- const { getNodes } = store.getState()
- const nodes = getNodes()
- const childrenNodes = nodes.filter(n => n.parentId === nodeId && n.type !== CUSTOM_LOOP_START_NODE)
- return childrenNodes.map((child, index) => {
- const childNodeType = child.data.type as BlockEnum
- const nodesWithSameType = nodes.filter(node => node.data.type === childNodeType)
- const { newNode } = generateNewNode({
- data: {
- ...NODES_INITIAL_DATA[childNodeType],
- ...child.data,
- selected: false,
- _isBundled: false,
- _connectedSourceHandleIds: [],
- _connectedTargetHandleIds: [],
- title: nodesWithSameType.length > 0 ? `${t(`workflow.blocks.${childNodeType}`)} ${nodesWithSameType.length + 1}` : t(`workflow.blocks.${childNodeType}`),
- loop_id: newNodeId,
- },
- position: child.position,
- positionAbsolute: child.positionAbsolute,
- parentId: newNodeId,
- extent: child.extent,
- zIndex: child.zIndex,
- })
- newNode.id = `${newNodeId}${newNode.id + index}`
- return newNode
- })
- }, [store, t])
- return {
- handleNodeLoopRerender,
- handleNodeLoopChildDrag,
- handleNodeLoopChildSizeChange,
- handleNodeLoopChildrenCopy,
- }
- }
|