Skip to main content
Glama

Activepieces MCP Server

by eldoonreval
test-trigger-section.tsxβ€’13.7 kB
import { useQuery } from '@tanstack/react-query'; import deepEqual from 'deep-equal'; import { t } from 'i18next'; import { AlertCircle } from 'lucide-react'; import React, { useMemo, useRef, useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Button } from '@/components/ui/button'; import { Dot } from '@/components/ui/dot'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { LoadingSpinner } from '@/components/ui/spinner'; import { triggerEventsApi } from '@/features/flows/lib/trigger-events-api'; import { piecesHooks } from '@/features/pieces/lib/pieces-hook'; import { SeekPage, Trigger, TriggerEventWithPayload, TriggerTestStrategy, isNil, } from '@activepieces/shared'; import { useBuilderStateContext } from '../builder-hooks'; import { McpToolTestingDialog } from './custom-test-step/mcp-tool-testing-dialog'; import TestWebhookDialog from './custom-test-step/test-webhook-dialog'; import { TestSampleDataViewer } from './test-sample-data-viewer'; import testStepHooks from './test-step-hooks'; import { TestButtonTooltip } from './test-step-tooltip'; type TestTriggerSectionProps = { isSaving: boolean; flowVersionId: string; flowId: string; projectId: string; }; const ManualWebhookPieceTriggerTestButton = ({ isWebhookTestingDialogOpen, setIsWebhookTestingDialogOpen, }: { isWebhookTestingDialogOpen: boolean; setIsWebhookTestingDialogOpen: (open: boolean) => void; }) => { const [id, setId] = useState<number>(0); const formValues = useFormContext<Trigger>().getValues(); return ( <> <Button variant="default" size="sm" className="flex items-center gap-2" onClick={() => { setIsWebhookTestingDialogOpen(true); }} > {t('Generate Sample Data')} </Button> <TestWebhookDialog key={`test-webhook-dialog-${id}`} open={isWebhookTestingDialogOpen} onOpenChange={(val) => { if (!val) { setTimeout(() => { setId(id + 1); }, 200); } setIsWebhookTestingDialogOpen(val); }} testingMode="trigger" currentStep={formValues} /> </> ); }; function getSelectedId( sampleData: unknown, pollResults: TriggerEventWithPayload[], ) { if (sampleData === undefined) { return undefined; } return pollResults.find((result) => deepEqual(sampleData, result.payload)) ?.id; } const TestTriggerSection = React.memo( ({ isSaving, flowVersionId, flowId }: TestTriggerSectionProps) => { const form = useFormContext<Trigger>(); const formValues = form.getValues(); const isValid = form.formState.isValid; const abortControllerRef = useRef<AbortController>(new AbortController()); const lastTestDate = formValues.settings.inputUiInfo?.lastTestDate; const [isMcpToolTestingDialogOpen, setIsMcpToolTestingDialogOpen] = useState(false); const { pieceModel, isLoading: isPieceLoading } = piecesHooks.usePiece({ name: formValues.settings.pieceName, version: formValues.settings.pieceVersion, }); const mockData = pieceModel?.triggers?.[formValues.settings.triggerName]?.sampleData; const isMcpTool = formValues.settings.triggerName === 'mcp_tool'; const isSimulation = pieceModel?.triggers?.[formValues.settings.triggerName]?.testStrategy === TriggerTestStrategy.SIMULATION && !isMcpTool; const [errorMessage, setErrorMessage] = useState<string | undefined>( undefined, ); const { sampleData, sampleDataInput } = useBuilderStateContext((state) => { return { sampleData: state.sampleData[formValues.name], sampleDataInput: state.sampleDataInput[formValues.name], }; }); const { mutate: saveMockAsSampleData, isPending: isSavingMockdata } = testStepHooks.useSaveMockData({ onSuccess: () => { refetch(); }, }); const [isWebhookTestingDialogOpen, setIsWebhookTestingDialogOpen] = useState(false); const { mutate: simulateTrigger, isPending: isSimulating, reset: resetSimulation, } = testStepHooks.useSimulateTrigger({ setErrorMessage, onSuccess: async () => { await refetch(); setIsWebhookTestingDialogOpen(false); }, }); const { mutate: pollTrigger, isPending: isPollingTesting } = testStepHooks.usePollTrigger({ setErrorMessage, onSuccess: () => { refetch(); }, }); const { mutate: updateTriggerSampleData } = testStepHooks.useUpdateTriggerSampleData(); const { data: pollResults, refetch } = useQuery< SeekPage<TriggerEventWithPayload> >({ queryKey: ['triggerEvents', flowVersionId], queryFn: () => triggerEventsApi.list({ flowId: flowId, limit: 5, cursor: undefined, }), staleTime: 0, }); const sampleDataSelected = !isNil(lastTestDate) || !isNil(errorMessage); const isTestedBefore = !isNil( form.getValues().settings.inputUiInfo?.lastTestDate, ); const selectedId = useMemo( () => getSelectedId(sampleData, pollResults?.data ?? []), [sampleData, pollResults], ); if (isPieceLoading) { return null; } const showSampleDataViewer = sampleDataSelected && !isSimulating && !isSavingMockdata; const showSimulationSection = isSimulation && isSimulating; const showFirstTimeTestingSectionForSimulation = !isTestedBefore && !sampleDataSelected && isSimulation && !isSimulating; const showFirstTimeTestingSectionForPolling = !isTestedBefore && !sampleDataSelected && !isSimulation && !isSimulating && !isMcpTool; const showFirstTimeMcpToolTestingSection = !isTestedBefore && !sampleDataSelected && isMcpTool; const isWebhookPieceTrigger = pieceModel?.name === '@activepieces/piece-webhook' && formValues.settings.triggerName === 'catch_webhook'; const handleMcpToolTesting = () => { setIsMcpToolTestingDialogOpen(true); }; return ( <div> {showSampleDataViewer && ( <TestSampleDataViewer onRetest={ isSimulation ? () => { simulateTrigger(abortControllerRef.current.signal); } : isMcpTool ? handleMcpToolTesting : pollTrigger } isValid={isValid} isTesting={isPollingTesting} sampleData={sampleData} sampleDataInput={sampleDataInput ?? null} errorMessage={errorMessage} lastTestDate={lastTestDate} isSaving={isSaving} > {pollResults?.data && ( <div className="mb-3"> <Select value={selectedId} onValueChange={(value) => { const triggerEvent = pollResults?.data.find( (triggerEvent) => triggerEvent.id === value, ); if (triggerEvent) { updateTriggerSampleData(triggerEvent); } }} > <SelectTrigger className="w-full" disabled={pollResults && pollResults.data.length === 0} > {pollResults && pollResults.data.length > 0 ? ( <SelectValue placeholder={t('No sample data available')} ></SelectValue> ) : ( t('Old results were removed, retest for new sample data') )} </SelectTrigger> <SelectContent> {pollResults && pollResults.data.map((triggerEvent, index) => ( <SelectItem key={triggerEvent.id} value={triggerEvent.id} > {t('Result #') + (index + 1)} </SelectItem> ))} </SelectContent> </Select> <span className="text-sm mt-2 text-muted-foreground"> {t('The sample data can be used in the next steps.')} </span> </div> )} </TestSampleDataViewer> )} {showSimulationSection && ( <div className="flex flex-col gap-4 w-full"> <div className="flex gap-2 items-center justify-center w-full"> <LoadingSpinner className="w-4 h-4"></LoadingSpinner> <div>{t('Testing Trigger')}</div> <div className="flex-grow"></div> <Button variant="outline" size="sm" onClick={() => { resetSimulation(); abortControllerRef.current.abort(); abortControllerRef.current = new AbortController(); }} > {t('Cancel')} </Button> </div> <Alert className="bg-warning/5 border-warning/5 "> <AlertCircle className="h-4 w-4 text-warning" /> <div className="flex flex-col gap-1"> <AlertTitle>{t('Action Required')}:</AlertTitle> <AlertDescription> {!isWebhookPieceTrigger && t('testPieceWebhookTriggerNote', { pieceName: pieceModel.displayName, triggerName: pieceModel.triggers[formValues.settings.triggerName] .displayName, })} {isWebhookPieceTrigger && ( <div className="break-wrods"> {t( 'Send Data to the webhook URL to generate sample data to use in the next steps', )} </div> )} </AlertDescription> </div> </Alert> {isWebhookPieceTrigger && ( <ManualWebhookPieceTriggerTestButton isWebhookTestingDialogOpen={isWebhookTestingDialogOpen} setIsWebhookTestingDialogOpen={setIsWebhookTestingDialogOpen} /> )} </div> )} {showFirstTimeTestingSectionForSimulation && ( <div className="flex justify-center flex-col gap-2 items-center"> <TestButtonTooltip disabled={!isValid}> <Button variant="outline" size="sm" onClick={() => simulateTrigger(abortControllerRef.current.signal) } keyboardShortcut="G" onKeyboardShortcut={() => simulateTrigger(abortControllerRef.current.signal) } disabled={!isValid} > <Dot animation={true} variant={'primary'}></Dot> {t('Test Trigger')} </Button> </TestButtonTooltip> {!isNil(mockData) && ( <> {t('Or')} <Button variant="outline" size="sm" onClick={() => saveMockAsSampleData(mockData)} loading={isSavingMockdata} > {t('Use Mock Data')} </Button> </> )} </div> )} {showFirstTimeTestingSectionForPolling && ( <div className="flex justify-center"> <TestButtonTooltip disabled={!isValid}> <Button variant="outline" size="sm" onClick={() => { pollTrigger(); }} keyboardShortcut="G" onKeyboardShortcut={pollTrigger} loading={isPollingTesting || isMcpToolTestingDialogOpen} disabled={!isValid} > <Dot animation={true} variant={'primary'}></Dot> {t('Load Sample Data')} </Button> </TestButtonTooltip> </div> )} {showFirstTimeMcpToolTestingSection && ( <div className="flex justify-center"> <TestButtonTooltip disabled={!isValid}> <Button variant="outline" size="sm" onClick={() => { handleMcpToolTesting(); }} keyboardShortcut="G" onKeyboardShortcut={handleMcpToolTesting} loading={isPollingTesting || isMcpToolTestingDialogOpen} disabled={!isValid} > <Dot animation={true} variant={'primary'}></Dot> {t('Test Tool')} </Button> </TestButtonTooltip> </div> )} {isMcpTool && ( <McpToolTestingDialog open={isMcpToolTestingDialogOpen} onOpenChange={setIsMcpToolTestingDialogOpen} onTestingSuccess={() => { refetch(); }} /> )} </div> ); }, ); TestTriggerSection.displayName = 'TestTriggerSection'; export { TestTriggerSection };

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/eldoonreval/activepieces'

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