Skip to main content
Glama

mcp-google-sheets

dynamic-piece-property.tsx6.05 kB
import deepEqual from 'deep-equal'; import React, { useState, useRef, useContext } from 'react'; import { useFormContext, useWatch } from 'react-hook-form'; import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect'; import { useBuilderStateContext } from '@/app/builder/builder-hooks'; import { SkeletonList } from '@/components/ui/skeleton'; import { formUtils } from '@/features/pieces/lib/form-utils'; import { piecesHooks } from '@/features/pieces/lib/pieces-hooks'; import { PiecePropertyMap, PropertyType } from '@activepieces/pieces-framework'; import { FlowAction, FlowTrigger } from '@activepieces/shared'; import { useStepSettingsContext } from '../step-settings/step-settings-context'; import { AutoPropertiesFormComponent } from './auto-properties-form'; import { DynamicPropertiesErrorBoundary } from './dynamic-piece-properties-error-boundary'; import { DynamicPropertiesContext } from './dynamic-properties-context'; type DynamicPropertiesProps = { refreshers: string[]; propertyName: string; disabled: boolean; }; const DynamicPropertiesImplementation = React.memo( (props: DynamicPropertiesProps) => { const [flowVersion, readonly] = useBuilderStateContext((state) => [ state.flowVersion, state.readonly, ]); const form = useFormContext<FlowAction | FlowTrigger>(); const { updateFormSchema } = useStepSettingsContext(); const isFirstRender = useRef(true); const previousValues = useRef<undefined | unknown[]>(undefined); const { propertyLoadingFinished, propertyLoadingStarted } = useContext( DynamicPropertiesContext, ); const [propertyMap, setPropertyMap] = useState< PiecePropertyMap | undefined >(undefined); const newRefreshers = [...props.refreshers, 'auth']; const { mutate, isPending, error } = piecesHooks.usePieceOptions<PropertyType.DYNAMIC>({ onMutate: () => { propertyLoadingStarted(props.propertyName); }, onError: (error) => { console.error(error); propertyLoadingFinished(props.propertyName); }, onSuccess: () => { propertyLoadingFinished(props.propertyName); }, }); if (error) { throw error; } /* eslint-disable react-hooks/rules-of-hooks */ const refresherValues = newRefreshers.map((refresher) => useWatch({ name: `settings.input.${refresher}` as const, control: form.control, }), ); /* eslint-enable react-hooks/rules-of-hooks */ useDeepCompareEffectNoCheck(() => { const input: Record<string, unknown> = {}; newRefreshers.forEach((refresher, index) => { input[refresher] = refresherValues[index]; }); if ( !isFirstRender.current && !deepEqual(previousValues.current, refresherValues) ) { // the field state won't be cleared if you only unset the parent prop value if (propertyMap) { Object.keys(propertyMap).forEach((childPropName) => { form.setValue( `settings.input.${props.propertyName}.${childPropName}` as const, null, { shouldValidate: true, }, ); }); } form.setValue(`settings.input.${props.propertyName}` as const, null, { shouldValidate: true, }); } previousValues.current = refresherValues; isFirstRender.current = false; const { settings } = form.getValues(); const actionOrTriggerName = settings.actionName ?? settings.triggerName; const { pieceName, pieceVersion } = settings; mutate( { request: { pieceName, pieceVersion, propertyName: props.propertyName, actionOrTriggerName: actionOrTriggerName, input, flowVersionId: flowVersion.id, flowId: flowVersion.flowId, }, propertyType: PropertyType.DYNAMIC, }, { onSuccess: (response) => { const currentValue = form.getValues( `settings.input.${props.propertyName}`, ); const defaultValue = formUtils.getDefaultValueForStep({ props: response.options, existingInput: currentValue ?? {}, propertySettings: form.getValues().settings?.propertySettings?.[ props.propertyName ], }); setPropertyMap(response.options); updateFormSchema( `settings.input.${props.propertyName}`, response.options, ); if (!readonly) { form.setValue( `settings.propertySettings.${props.propertyName}.schema`, response.options, ); } form.setValue( `settings.input.${props.propertyName}`, defaultValue, { shouldValidate: true, shouldDirty: true, }, ); }, }, ); }, refresherValues); return ( <> {isPending && ( <SkeletonList numberOfItems={3} className="h-7"></SkeletonList> )} {!isPending && propertyMap && ( <AutoPropertiesFormComponent prefixValue={`settings.input.${props.propertyName}`} props={propertyMap} useMentionTextInput={true} disabled={props.disabled} allowDynamicValues={true} ></AutoPropertiesFormComponent> )} </> ); }, ); const DynamicProperties = React.memo((props: DynamicPropertiesProps) => { return ( <DynamicPropertiesErrorBoundary> <DynamicPropertiesImplementation {...props} /> </DynamicPropertiesErrorBoundary> ); }); DynamicPropertiesImplementation.displayName = 'DynamicPropertiesImplementation'; DynamicProperties.displayName = 'DynamicProperties'; export { DynamicProperties };

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