Feat: Click the edit tool button of the agent form to open the corresponding form #3221 (#9071)

### What problem does this PR solve?

Feat: Click the edit tool button of the agent form to open the
corresponding form #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-07-28 16:48:59 +08:00
committed by GitHub
parent 381f9df941
commit 35b1a5b7e0
6 changed files with 72 additions and 23 deletions

View File

@ -2,7 +2,13 @@ import { BlockButton } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import { Position } from '@xyflow/react';
import { PencilLine, X } from 'lucide-react';
import { PropsWithChildren, useCallback, useContext, useMemo } from 'react';
import {
MouseEventHandler,
PropsWithChildren,
useCallback,
useContext,
useMemo,
} from 'react';
import { Operator } from '../../constant';
import { AgentInstanceContext } from '../../context';
import { useFindMcpById } from '../../hooks/use-find-mcp-by-id';
@ -35,23 +41,20 @@ export function ToolCard({
type ActionButtonProps<T> = {
record: T;
deleteRecord(record: T): void;
edit(record: T): void;
edit: MouseEventHandler<HTMLOrSVGElement>;
};
function ActionButton<T>({ edit, deleteRecord, record }: ActionButtonProps<T>) {
function ActionButton<T>({ deleteRecord, record, edit }: ActionButtonProps<T>) {
const handleDelete = useCallback(() => {
deleteRecord(record);
}, [deleteRecord, record]);
const handleEdit = useCallback(() => {
edit(record);
}, [edit, record]);
return (
<div className="flex items-center gap-2 text-text-sub-title">
<PencilLine
className="size-4 cursor-pointer"
data-tool={record}
onClick={handleEdit}
onClick={edit}
/>
<X className="size-4 cursor-pointer" onClick={handleDelete} />
</div>
@ -64,6 +67,21 @@ export function AgentTools() {
const { mcpIds } = useGetAgentMCPIds();
const { findMcpById } = useFindMcpById();
const { deleteNodeMCP } = useDeleteAgentNodeMCP();
const { showFormDrawer } = useContext(AgentInstanceContext);
const { clickedNodeId, findAgentToolNodeById, selectNodeIds } = useGraphStore(
(state) => state,
);
const handleEdit: MouseEventHandler<SVGSVGElement> = useCallback(
(e) => {
const toolNodeId = findAgentToolNodeById(clickedNodeId);
if (toolNodeId) {
selectNodeIds([toolNodeId]);
showFormDrawer(e, toolNodeId);
}
},
[clickedNodeId, findAgentToolNodeById, selectNodeIds, showFormDrawer],
);
return (
<section className="space-y-2.5">
@ -74,8 +92,8 @@ export function AgentTools() {
{x}
<ActionButton
record={x}
edit={() => {}}
deleteRecord={deleteNodeTool(x)}
edit={handleEdit}
></ActionButton>
</ToolCard>
))}
@ -84,8 +102,8 @@ export function AgentTools() {
{findMcpById(id)?.name}
<ActionButton
record={id}
edit={() => {}}
deleteRecord={deleteNodeMCP(id)}
edit={handleEdit}
></ActionButton>
</ToolCard>
))}
@ -99,8 +117,17 @@ export function AgentTools() {
export function Agents({ node }: INextOperatorForm) {
const { addCanvasNode } = useContext(AgentInstanceContext);
const { deleteAgentDownstreamNodesById, edges, getNode } = useGraphStore(
(state) => state,
const { deleteAgentDownstreamNodesById, edges, getNode, selectNodeIds } =
useGraphStore((state) => state);
const { showFormDrawer } = useContext(AgentInstanceContext);
const handleEdit = useCallback(
(nodeId: string): MouseEventHandler<SVGSVGElement> =>
(e) => {
selectNodeIds([nodeId]);
showFormDrawer(e, nodeId);
},
[selectNodeIds, showFormDrawer],
);
const subBottomAgentNodeIds = useMemo(() => {
@ -119,8 +146,8 @@ export function Agents({ node }: INextOperatorForm) {
{currentNode?.data.name}
<ActionButton
record={id}
edit={() => {}}
deleteRecord={deleteAgentDownstreamNodesById}
edit={handleEdit(id)}
></ActionButton>
</ToolCard>
);