Skip to main content
Glama
flow-dialog-content.tsx4.46 kB
import { t } from 'i18next'; import { Workflow } from 'lucide-react'; import { useMemo } from 'react'; import { useDebounce } from 'use-debounce'; import { Checkbox } from '@/components/ui/checkbox'; import { PieceIconList } from '@/features/pieces/components/piece-icon-list'; import { AgentFlowTool, AgentToolType, PopulatedFlow, } from '@activepieces/shared'; import { CreateMcpFlowButton } from './create-mcp-flow-button'; import { flowDialogUtils } from './flow-dialog-utils'; interface FlowDialogContentProps { flows: PopulatedFlow[]; selectedFlows: AgentFlowTool[]; setSelectedFlows: ( value: AgentFlowTool[] | ((prev: AgentFlowTool[]) => AgentFlowTool[]), ) => void; searchQuery: string; } export const FlowDialogContent = ({ flows, selectedFlows, setSelectedFlows, searchQuery, }: FlowDialogContentProps) => { const [debouncedQuery] = useDebounce(searchQuery, 300); const filteredFlows = useMemo(() => { if (!debouncedQuery) return flows; const query = debouncedQuery.toLowerCase(); return flows.filter((flow) => flow.version.displayName.toLowerCase().includes(query), ); }, [flows, debouncedQuery]); const isSelected = (flow: PopulatedFlow) => selectedFlows.some((tool) => tool.externalFlowId === flow.externalId); const toggleFlow = (flow: PopulatedFlow) => { setSelectedFlows((prev) => { const exists = prev.some( (tool) => tool.externalFlowId === flow.externalId, ); if (exists) { return prev.filter((tool) => tool.externalFlowId !== flow.externalId); } return [ ...prev, { externalFlowId: flow.externalId, toolName: `${flow.version.displayName}_${flow.id}`, type: AgentToolType.FLOW, }, ]; }); }; return ( <> <div className="flex flex-col px-4 py-2"> {filteredFlows.map((flow, index) => { const helperText = flowDialogUtils.getFlowTooltip(flow); const isSelectable = flowDialogUtils.isFlowSelectable(flow); const selected = isSelected(flow); return ( <div key={flow.id}> <div className={` flex items-center gap-4 px-4 py-2 h-14 rounded-md cursor-pointer hover:bg-accent hover:text-accent-foreground ${selected ? 'bg-accent' : ''} ${!isSelectable ? 'opacity-50 cursor-not-allowed' : ''} `} onClick={() => isSelectable && toggleFlow(flow)} > <Checkbox checked={selected} disabled={!isSelectable} onCheckedChange={() => isSelectable && toggleFlow(flow)} onClick={(e) => e.stopPropagation()} /> <div className="flex-1 min-w-0"> <div className="truncate text-sm font-medium"> {flow.version.displayName} </div> {helperText && ( <div className="text-xs text-muted-foreground truncate"> {helperText} </div> )} </div> <PieceIconList trigger={flow.version.trigger} maxNumberOfIconsToShow={3} /> </div> {index < filteredFlows.length - 1 && ( <div className="h-px bg-border my-1" /> )} </div> ); })} </div> {filteredFlows.length === 0 && ( <div className="flex flex-col items-center justify-center py-20 text-center"> <div className="mb-5 flex size-14 items-center justify-center rounded-xl border bg-muted/40"> <Workflow className="size-7 text-muted-foreground" /> </div> <div className="text-base font-semibold text-foreground"> {t('No flows found')} </div> <div className="mt-2 max-w-sm text-sm leading-relaxed text-muted-foreground"> {searchQuery ? t('Try adjusting your search or create a new flow.') : t('Create a flow to use it as a tool in your agent.')} </div> {!searchQuery && ( <div className="mt-6"> <CreateMcpFlowButton /> </div> )} </div> )} </> ); };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server