Skip to main content
Glama

mcp-google-sheets

array-property.tsx6.38 kB
import { t } from 'i18next'; import { Plus, TrashIcon } from 'lucide-react'; import { nanoid } from 'nanoid'; import React, { useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { ArrayInput } from '@/components/custom/array-input'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { TextWithIcon } from '@/components/ui/text-with-icon'; import { ArrayProperty, ArraySubProps, PropertyType, } from '@activepieces/pieces-framework'; import { AutoPropertiesFormComponent } from './auto-properties-form'; import { TextInputWithMentions } from './text-input-with-mentions'; type ArrayPropertyProps = { inputName: string; useMentionTextInput: boolean; arrayProperty: ArrayProperty<boolean>; disabled: boolean; }; type ArrayField = { id: string; value: string | Record<string, unknown>; }; const getDefaultValuesForInputs = (arrayProperties: ArraySubProps<boolean>) => { return Object.entries(arrayProperties).reduce((acc, [key, value]) => { switch (value.type) { case PropertyType.LONG_TEXT: case PropertyType.SHORT_TEXT: case PropertyType.NUMBER: case PropertyType.JSON: case PropertyType.COLOR: return { ...acc, [key]: '', }; case PropertyType.CHECKBOX: return { ...acc, [key]: false, }; case PropertyType.STATIC_DROPDOWN: case PropertyType.STATIC_MULTI_SELECT_DROPDOWN: case PropertyType.MULTI_SELECT_DROPDOWN: case PropertyType.DATE_TIME: return { ...acc, [key]: null, }; case PropertyType.FILE: return { ...acc, [key]: null, }; } }, {} as Record<string, unknown>); }; const ArrayPieceProperty = React.memo( ({ inputName, useMentionTextInput, disabled, arrayProperty, }: ArrayPropertyProps) => { const form = useFormContext(); const [fields, setFields] = useState<ArrayField[]>(() => { const formValues = form.getValues(inputName); if (formValues) { return formValues.map((value: string | Record<string, unknown>) => ({ id: nanoid(), value, })); } else { return []; } }); const updateFormValue = (newFields: ArrayField[]) => { form.setValue( inputName, newFields.map((f) => f.value), { shouldValidate: true }, ); }; const append = () => { //passing empty object will result in react form putting in the initial values when the user first started editing const value = arrayProperty.properties ? getDefaultValuesForInputs(arrayProperty.properties) : ''; const formValues = form.getValues(inputName) || []; const newFields = [ ...formValues.map((value: string | Record<string, unknown>) => ({ id: nanoid(), value, })), { id: nanoid(), value }, ]; setFields(newFields); updateFormValue(newFields); }; const remove = (index: number) => { const currentFields: ArrayField[] = form .getValues(inputName) .map((value: string | Record<string, unknown>) => ({ id: nanoid(), value, })); const newFields = currentFields.filter((_, i) => i !== index); setFields(newFields); updateFormValue(newFields); }; return ( <> {arrayProperty.properties && ( <> <div className="flex w-full flex-col gap-4"> {fields.map((field, index) => ( <div className="p-4 border rounded-md flex flex-col gap-4" key={'array-item-' + field.id} > <div className="flex justify-between"> <div className="font-semibold"> #{index + 1}</div> <Button variant="outline" size="icon" className="size-8 shrink-0" onClick={() => { remove(index); }} disabled={disabled} > <TrashIcon className="size-4 text-destructive" aria-hidden="true" /> <span className="sr-only">{t('Remove')}</span> </Button> </div> <AutoPropertiesFormComponent prefixValue={`${inputName}.[${index}]`} props={arrayProperty.properties!} useMentionTextInput={useMentionTextInput} allowDynamicValues={false} disabled={disabled} onValueChange={() => { form.trigger(inputName); }} ></AutoPropertiesFormComponent> </div> ))} </div> {!disabled && ( <Button variant="outline" size="sm" className="mt-2" onClick={() => { append(); }} type="button" > <TextWithIcon icon={<Plus size={18} />} text={t('Add Item')} /> </Button> )} </> )} {!arrayProperty.properties && ( <ArrayInput inputName={inputName} disabled={disabled} required={arrayProperty.required} customInputNode={(onChange, value, disabled) => { if (!useMentionTextInput) { return ( <Input value={value} onChange={(e) => onChange(e.target.value)} disabled={disabled} /> ); } return ( <TextInputWithMentions initialValue={value} onChange={(newValue) => onChange(newValue)} disabled={disabled} /> ); }} /> )} </> ); }, ); ArrayPieceProperty.displayName = 'ArrayPieceProperty'; export { ArrayPieceProperty };

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