Feat: A pipeline's child node can only have one node #9869 (#10695)

### What problem does this PR solve?

Feat: A pipeline's child node can only have one node #9869
### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-10-21 13:55:46 +08:00
committed by GitHub
parent 594bf485d4
commit 41a647fe32
3 changed files with 18 additions and 3 deletions

View File

@ -1533,8 +1533,8 @@ This delimiter is used to split the input text into several text pieces echo of
'Your users will see this welcome message at the beginning.',
modeTip: 'The mode defines how the workflow is initiated.',
mode: 'Mode',
conversational: 'conversational',
task: 'task',
conversational: 'Conversational',
task: 'Task',
beginInputTip:
'By defining input parameters, this content can be accessed by other components in subsequent processes.',
query: 'Query variables',

View File

@ -5,6 +5,8 @@ import { Plus } from 'lucide-react';
import { useMemo } from 'react';
import { NodeHandleId } from '../../constant';
import { HandleContext } from '../../context';
import { useIsPipeline } from '../../hooks/use-is-pipeline';
import useGraphStore from '../../store';
import { useDropdownManager } from '../context';
import { NextStepDropdown } from './dropdown/next-step-dropdown';
@ -14,9 +16,12 @@ export function CommonHandle({
...props
}: HandleProps & { nodeId: string }) {
const { visible, hideModal, showModal } = useSetModalState();
const { canShowDropdown, setActiveDropdown, clearActiveDropdown } =
useDropdownManager();
const { hasChildNode } = useGraphStore((state) => state);
const isPipeline = useIsPipeline();
const isConnectable = !(isPipeline && hasChildNode(nodeId)); // Using useMemo will cause isConnectable to not be updated when the subsequent connection line is deleted
const value = useMemo(
() => ({
@ -33,6 +38,7 @@ export function CommonHandle({
<HandleContext.Provider value={value}>
<Handle
{...props}
isConnectable={isConnectable}
className={cn(
'inline-flex justify-center items-center !bg-accent-primary !border-none group-hover:!size-4 group-hover:!rounded-sm',
className,
@ -40,6 +46,10 @@ export function CommonHandle({
onClick={(e) => {
e.stopPropagation();
if (!isConnectable) {
return;
}
if (!canShowDropdown()) {
return;
}

View File

@ -89,6 +89,7 @@ export type RFState = {
) => void; // Deleting a condition of a classification operator will delete the related edge
findAgentToolNodeById: (id: string | null) => string | undefined;
selectNodeIds: (nodeIds: string[]) => void;
hasChildNode: (nodeId: string) => boolean;
};
// this is our useStore hook that we can use in our components to get parts of the store and call actions
@ -527,6 +528,10 @@ const useGraphStore = create<RFState>()(
})),
);
},
hasChildNode: (nodeId) => {
const { edges } = get();
return edges.some((edge) => edge.source === nodeId);
},
})),
{ name: 'graph', trace: true },
),