mirror of
https://github.com/baptisteArno/typebot.io.git
synced 2026-06-19 21:04:33 +08:00
parent
77b3acb2d7
commit
445196e37d
@ -1,225 +1,97 @@
|
||||
import { Text, TextProps } from '@chakra-ui/react'
|
||||
import React from 'react'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
import { TFnType, useTranslate } from '@tolgee/react'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants'
|
||||
import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants'
|
||||
import { Block } from '@typebot.io/schemas'
|
||||
import { ForgedBlockLabel } from '@/features/forge/ForgedBlockLabel'
|
||||
import { isForgedBlockType } from '@typebot.io/schemas/features/blocks/forged/helpers'
|
||||
import {
|
||||
isBubbleBlockType,
|
||||
isInputBlockType,
|
||||
isIntegrationBlockType,
|
||||
isLogicBlockType,
|
||||
} from '@typebot.io/schemas/helpers'
|
||||
|
||||
type Props = { type: Block['type'] } & TextProps
|
||||
|
||||
export const BlockLabel = ({ type, ...props }: Props): JSX.Element => {
|
||||
const { t } = useTranslate()
|
||||
|
||||
switch (type) {
|
||||
case 'start':
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.start.label')}
|
||||
</Text>
|
||||
)
|
||||
case BubbleBlockType.TEXT:
|
||||
case InputBlockType.TEXT:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.text.label')}
|
||||
</Text>
|
||||
)
|
||||
case BubbleBlockType.IMAGE:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.image.label')}
|
||||
</Text>
|
||||
)
|
||||
case BubbleBlockType.VIDEO:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.video.label')}
|
||||
</Text>
|
||||
)
|
||||
case BubbleBlockType.EMBED:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.embed.label')}
|
||||
</Text>
|
||||
)
|
||||
case BubbleBlockType.AUDIO:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.audio.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.NUMBER:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.number.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.EMAIL:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.email.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.URL:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.website.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.DATE:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.date.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.PHONE:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.phone.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.CHOICE:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.button.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.PICTURE_CHOICE:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.picChoice.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.PAYMENT:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.payment.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.RATING:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.rating.label')}
|
||||
</Text>
|
||||
)
|
||||
case InputBlockType.FILE:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.file.label')}
|
||||
</Text>
|
||||
)
|
||||
case LogicBlockType.SET_VARIABLE:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.setVariable.label')}
|
||||
</Text>
|
||||
)
|
||||
case LogicBlockType.CONDITION:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.condition.label')}
|
||||
</Text>
|
||||
)
|
||||
case LogicBlockType.REDIRECT:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.redirect.label')}
|
||||
</Text>
|
||||
)
|
||||
case LogicBlockType.SCRIPT:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.script.label')}
|
||||
</Text>
|
||||
)
|
||||
case LogicBlockType.TYPEBOT_LINK:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.typebot.label')}
|
||||
</Text>
|
||||
)
|
||||
case LogicBlockType.WAIT:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.wait.label')}
|
||||
</Text>
|
||||
)
|
||||
case LogicBlockType.JUMP:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.jump.label')}
|
||||
</Text>
|
||||
)
|
||||
case LogicBlockType.AB_TEST:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.abTest.label')}
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.GOOGLE_SHEETS:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.sheets.label')}
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.GOOGLE_ANALYTICS:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.analytics.label')}
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.WEBHOOK:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
HTTP request
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.ZAPIER:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.zapier.label')}
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.MAKE_COM:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.makecom.label')}
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.PABBLY_CONNECT:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.pabbly.label')}
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.EMAIL:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.email.label')}
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.CHATWOOT:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.chatwoot.label')}
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.OPEN_AI:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.openai.label')}
|
||||
</Text>
|
||||
)
|
||||
case IntegrationBlockType.PIXEL:
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{t('editor.sidebarBlock.pixel.label')}
|
||||
</Text>
|
||||
)
|
||||
default:
|
||||
return <ForgedBlockLabel type={type} {...props} />
|
||||
}
|
||||
if (isForgedBlockType(type))
|
||||
return <ForgedBlockLabel type={type} {...props} />
|
||||
|
||||
const label = isBubbleBlockType(type)
|
||||
? getBubbleBlockLabel(t)[type]
|
||||
: isInputBlockType(type)
|
||||
? getInputBlockLabel(t)[type]
|
||||
: isLogicBlockType(type)
|
||||
? getLogicBlockLabel(t)[type]
|
||||
: isIntegrationBlockType(type)
|
||||
? getIntegrationBlockLabel(t)[type]
|
||||
: t('editor.sidebarBlock.start.label')
|
||||
|
||||
return (
|
||||
<Text fontSize="sm" {...props}>
|
||||
{label}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
export const getBubbleBlockLabel = (
|
||||
t: TFnType
|
||||
): Record<BubbleBlockType, string> => ({
|
||||
[BubbleBlockType.TEXT]: t('editor.sidebarBlock.text.label'),
|
||||
[BubbleBlockType.IMAGE]: t('editor.sidebarBlock.image.label'),
|
||||
[BubbleBlockType.VIDEO]: t('editor.sidebarBlock.video.label'),
|
||||
[BubbleBlockType.EMBED]: t('editor.sidebarBlock.embed.label'),
|
||||
[BubbleBlockType.AUDIO]: t('editor.sidebarBlock.audio.label'),
|
||||
})
|
||||
|
||||
export const getInputBlockLabel = (
|
||||
t: TFnType
|
||||
): Record<InputBlockType, string> => ({
|
||||
[InputBlockType.NUMBER]: t('editor.sidebarBlock.number.label'),
|
||||
[InputBlockType.EMAIL]: t('editor.sidebarBlock.email.label'),
|
||||
[InputBlockType.TEXT]: t('editor.sidebarBlock.text.label'),
|
||||
[InputBlockType.URL]: t('editor.sidebarBlock.website.label'),
|
||||
[InputBlockType.DATE]: t('editor.sidebarBlock.date.label'),
|
||||
[InputBlockType.PHONE]: t('editor.sidebarBlock.phone.label'),
|
||||
[InputBlockType.CHOICE]: t('editor.sidebarBlock.button.label'),
|
||||
[InputBlockType.PICTURE_CHOICE]: t('editor.sidebarBlock.picChoice.label'),
|
||||
[InputBlockType.PAYMENT]: t('editor.sidebarBlock.payment.label'),
|
||||
[InputBlockType.RATING]: t('editor.sidebarBlock.rating.label'),
|
||||
[InputBlockType.FILE]: t('editor.sidebarBlock.file.label'),
|
||||
})
|
||||
|
||||
export const getLogicBlockLabel = (
|
||||
t: TFnType
|
||||
): Record<LogicBlockType, string> => ({
|
||||
[LogicBlockType.SET_VARIABLE]: t('editor.sidebarBlock.setVariable.label'),
|
||||
[LogicBlockType.CONDITION]: t('editor.sidebarBlock.condition.label'),
|
||||
[LogicBlockType.REDIRECT]: t('editor.sidebarBlock.redirect.label'),
|
||||
[LogicBlockType.SCRIPT]: t('editor.sidebarBlock.script.label'),
|
||||
[LogicBlockType.TYPEBOT_LINK]: t('editor.sidebarBlock.typebot.label'),
|
||||
[LogicBlockType.WAIT]: t('editor.sidebarBlock.wait.label'),
|
||||
[LogicBlockType.JUMP]: t('editor.sidebarBlock.jump.label'),
|
||||
[LogicBlockType.AB_TEST]: t('editor.sidebarBlock.abTest.label'),
|
||||
})
|
||||
|
||||
export const getIntegrationBlockLabel = (
|
||||
t: TFnType
|
||||
): Record<IntegrationBlockType, string> => ({
|
||||
[IntegrationBlockType.GOOGLE_SHEETS]: t('editor.sidebarBlock.sheets.label'),
|
||||
[IntegrationBlockType.GOOGLE_ANALYTICS]: t(
|
||||
'editor.sidebarBlock.analytics.label'
|
||||
),
|
||||
[IntegrationBlockType.WEBHOOK]: 'HTTP request',
|
||||
[IntegrationBlockType.ZAPIER]: t('editor.sidebarBlock.zapier.label'),
|
||||
[IntegrationBlockType.MAKE_COM]: t('editor.sidebarBlock.makecom.label'),
|
||||
[IntegrationBlockType.PABBLY_CONNECT]: t('editor.sidebarBlock.pabbly.label'),
|
||||
[IntegrationBlockType.EMAIL]: t('editor.sidebarBlock.email.label'),
|
||||
[IntegrationBlockType.CHATWOOT]: t('editor.sidebarBlock.chatwoot.label'),
|
||||
[IntegrationBlockType.OPEN_AI]: t('editor.sidebarBlock.openai.label'),
|
||||
[IntegrationBlockType.PIXEL]: t('editor.sidebarBlock.pixel.label'),
|
||||
})
|
||||
|
||||
@ -19,13 +19,19 @@ import { LockedIcon, UnlockedIcon } from '@/components/icons'
|
||||
import { BlockCardOverlay } from './BlockCardOverlay'
|
||||
import { headerHeight } from '../constants'
|
||||
import { useTranslate } from '@tolgee/react'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants'
|
||||
import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants'
|
||||
import { BlockV6 } from '@typebot.io/schemas'
|
||||
import { useDebouncedCallback } from 'use-debounce'
|
||||
import { forgedBlocks } from '@typebot.io/forge-repository/definitions'
|
||||
import {
|
||||
getBubbleBlockLabel,
|
||||
getInputBlockLabel,
|
||||
getIntegrationBlockLabel,
|
||||
getLogicBlockLabel,
|
||||
} from './BlockLabel'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
|
||||
// Integration blocks migrated to forged blocks
|
||||
const legacyIntegrationBlocks = [IntegrationBlockType.OPEN_AI]
|
||||
@ -92,9 +98,8 @@ export const BlocksSideBar = () => {
|
||||
}) => {
|
||||
setSearchInput(event.target.value)
|
||||
}
|
||||
const blocksArray = Object.values(forgedBlocks)
|
||||
|
||||
const filteredForgedBlockIds = blocksArray
|
||||
const filteredForgedBlockIds = Object.values(forgedBlocks)
|
||||
.filter((block) => {
|
||||
return (
|
||||
block.id.toLowerCase().includes(searchInput.toLowerCase()) ||
|
||||
@ -107,6 +112,35 @@ export const BlocksSideBar = () => {
|
||||
})
|
||||
.map((block) => block.id)
|
||||
|
||||
const filteredBubbleBlockTypes = Object.values(BubbleBlockType).filter(
|
||||
(type) =>
|
||||
getBubbleBlockLabel(t)
|
||||
[type].toLowerCase()
|
||||
.includes(searchInput.toLowerCase())
|
||||
)
|
||||
|
||||
const filteredInputBlockTypes = Object.values(InputBlockType).filter((type) =>
|
||||
getInputBlockLabel(t)
|
||||
[type].toLowerCase()
|
||||
.includes(searchInput.toLowerCase())
|
||||
)
|
||||
|
||||
const filteredLogicBlockTypes = Object.values(LogicBlockType).filter((type) =>
|
||||
getLogicBlockLabel(t)
|
||||
[type].toLowerCase()
|
||||
.includes(searchInput.toLowerCase())
|
||||
)
|
||||
|
||||
const filteredIntegrationBlockTypes = Object.values(
|
||||
IntegrationBlockType
|
||||
).filter(
|
||||
(type) =>
|
||||
getIntegrationBlockLabel(t)
|
||||
[type].toLowerCase()
|
||||
.includes(searchInput.toLowerCase()) &&
|
||||
!legacyIntegrationBlocks.includes(type)
|
||||
)
|
||||
|
||||
return (
|
||||
<Flex
|
||||
w="360px"
|
||||
@ -169,17 +203,9 @@ export const BlocksSideBar = () => {
|
||||
{t('editor.sidebarBlocks.blockType.bubbles.heading')}
|
||||
</Text>
|
||||
<SimpleGrid columns={2} spacing="3">
|
||||
{Object.values(BubbleBlockType)
|
||||
.filter((type) =>
|
||||
type.toLowerCase().includes(searchInput.toLowerCase())
|
||||
)
|
||||
.map((type) => (
|
||||
<BlockCard
|
||||
key={type}
|
||||
type={type}
|
||||
onMouseDown={handleMouseDown}
|
||||
/>
|
||||
))}
|
||||
{filteredBubbleBlockTypes.map((type) => (
|
||||
<BlockCard key={type} type={type} onMouseDown={handleMouseDown} />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
|
||||
@ -188,17 +214,9 @@ export const BlocksSideBar = () => {
|
||||
{t('editor.sidebarBlocks.blockType.inputs.heading')}
|
||||
</Text>
|
||||
<SimpleGrid columns={2} spacing="3">
|
||||
{Object.values(InputBlockType)
|
||||
.filter((type) =>
|
||||
type.toLowerCase().includes(searchInput.toLowerCase())
|
||||
)
|
||||
.map((type) => (
|
||||
<BlockCard
|
||||
key={type}
|
||||
type={type}
|
||||
onMouseDown={handleMouseDown}
|
||||
/>
|
||||
))}
|
||||
{filteredInputBlockTypes.map((type) => (
|
||||
<BlockCard key={type} type={type} onMouseDown={handleMouseDown} />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
|
||||
@ -207,17 +225,9 @@ export const BlocksSideBar = () => {
|
||||
{t('editor.sidebarBlocks.blockType.logic.heading')}
|
||||
</Text>
|
||||
<SimpleGrid columns={2} spacing="3">
|
||||
{Object.values(LogicBlockType)
|
||||
.filter((type) =>
|
||||
type.toLowerCase().includes(searchInput.toLowerCase())
|
||||
)
|
||||
.map((type) => (
|
||||
<BlockCard
|
||||
key={type}
|
||||
type={type}
|
||||
onMouseDown={handleMouseDown}
|
||||
/>
|
||||
))}
|
||||
{filteredLogicBlockTypes.map((type) => (
|
||||
<BlockCard key={type} type={type} onMouseDown={handleMouseDown} />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
|
||||
@ -226,12 +236,8 @@ export const BlocksSideBar = () => {
|
||||
{t('editor.sidebarBlocks.blockType.integrations.heading')}
|
||||
</Text>
|
||||
<SimpleGrid columns={2} spacing="3">
|
||||
{Object.values(IntegrationBlockType)
|
||||
.filter((type) =>
|
||||
type.toLowerCase().includes(searchInput.toLowerCase())
|
||||
)
|
||||
{filteredIntegrationBlockTypes
|
||||
.concat(filteredForgedBlockIds as any)
|
||||
.filter((type) => !legacyIntegrationBlocks.includes(type))
|
||||
.map((type) => (
|
||||
<BlockCard
|
||||
key={type}
|
||||
|
||||
@ -13,7 +13,6 @@ import {
|
||||
ConditionBlock,
|
||||
IntegrationBlock,
|
||||
HttpRequestBlock,
|
||||
BlockWithOptionsType,
|
||||
BlockWithOptions,
|
||||
} from './features/blocks'
|
||||
import { BubbleBlockType } from './features/blocks/bubbles/constants'
|
||||
@ -79,6 +78,17 @@ export const isBubbleBlockType = (
|
||||
): type is BubbleBlockType =>
|
||||
(Object.values(BubbleBlockType) as string[]).includes(type)
|
||||
|
||||
export const isInputBlockType = (type: Block['type']): type is InputBlockType =>
|
||||
(Object.values(InputBlockType) as string[]).includes(type)
|
||||
|
||||
export const isIntegrationBlockType = (
|
||||
type: Block['type']
|
||||
): type is IntegrationBlockType =>
|
||||
(Object.values(IntegrationBlockType) as string[]).includes(type)
|
||||
|
||||
export const isLogicBlockType = (type: Block['type']): type is LogicBlockType =>
|
||||
(Object.values(LogicBlockType) as string[]).includes(type)
|
||||
|
||||
export const blockHasOptions = (block: Block): block is BlockWithOptions =>
|
||||
'options' in block
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user