2
0
Files
bot/apps/builder/src/features/forge/components/ForgeSelectInput.tsx

127 lines
3.1 KiB
TypeScript
Raw Normal View History

/* eslint-disable @typescript-eslint/no-explicit-any */
import { MoreInfoTooltip } from '@/components/MoreInfoTooltip'
import { Select } from '@/components/inputs/Select'
import { VariablesButton } from '@/features/variables/components/VariablesButton'
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
import { useToast } from '@/hooks/useToast'
import { trpc } from '@/lib/trpc'
import {
FormControl,
FormHelperText,
FormLabel,
HStack,
Stack,
} from '@chakra-ui/react'
import {
ForgedBlockDefinition,
ForgedBlock,
} from '@typebot.io/forge-repository/types'
import { ReactNode, useMemo } from 'react'
import { findFetcher } from '../helpers/findFetcher'
type Props = {
blockDef: ForgedBlockDefinition
defaultValue?: string
fetcherId: string
options: ForgedBlock['options']
placeholder?: string
label?: string
helperText?: ReactNode
moreInfoTooltip?: string
direction?: 'row' | 'column'
isRequired?: boolean
2024-01-03 16:29:41 +01:00
width?: 'full'
withVariableButton?: boolean
onChange: (value: string | undefined) => void
}
export const ForgeSelectInput = ({
defaultValue,
fetcherId,
options,
blockDef,
placeholder,
label,
helperText,
moreInfoTooltip,
isRequired,
direction = 'column',
2024-01-03 16:29:41 +01:00
width,
withVariableButton = false,
onChange,
}: Props) => {
const { workspace } = useWorkspace()
const { showToast } = useToast()
const fetcher = useMemo(
() => findFetcher(blockDef, fetcherId),
[blockDef, fetcherId]
)
const { data } = trpc.forge.fetchSelectItems.useQuery(
{
integrationId: blockDef.id,
options: pick(
options,
(blockDef.auth ? ['credentialsId'] : []).concat(
fetcher?.dependencies ?? []
)
),
workspaceId: workspace?.id as string,
fetcherId,
},
{
enabled: !!workspace?.id && !!fetcher,
onError: (error) => {
showToast({
description: error.message,
status: 'error',
})
},
}
)
return (
<FormControl
isRequired={isRequired}
as={direction === 'column' ? Stack : HStack}
justifyContent="space-between"
2024-01-03 16:29:41 +01:00
width={label || width === 'full' ? 'full' : 'auto'}
spacing={direction === 'column' ? 2 : 3}
>
{label && (
<FormLabel mb="0" mr="0" flexShrink={0}>
{label}{' '}
{moreInfoTooltip && (
<MoreInfoTooltip>{moreInfoTooltip}</MoreInfoTooltip>
)}
</FormLabel>
)}
<HStack spacing="0">
<Select
items={data?.items}
selectedItem={defaultValue}
onSelect={onChange}
placeholder={placeholder}
/>
{withVariableButton ? (
<VariablesButton
onSelectVariable={(variable) => {
onChange(`{{${variable.name}}}`)
}}
/>
) : null}
</HStack>
{helperText && <FormHelperText mt="0">{helperText}</FormHelperText>}
</FormControl>
)
}
function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
if (!obj) return {} as Pick<T, K>
const ret: any = {}
keys.forEach((key) => {
ret[key] = obj[key]
})
return ret
}