✨ Add new Jump block
Also improve Select input with a clear button Closes #186
This commit is contained in:
@@ -51,9 +51,9 @@ export const GoogleSheetsSettingsBody = ({
|
||||
)
|
||||
const handleCredentialsIdChange = (credentialsId?: string) =>
|
||||
onOptionsChange({ ...omit(options, 'credentialsId'), credentialsId })
|
||||
const handleSpreadsheetIdChange = (spreadsheetId: string) =>
|
||||
const handleSpreadsheetIdChange = (spreadsheetId: string | undefined) =>
|
||||
onOptionsChange({ ...options, spreadsheetId })
|
||||
const handleSheetIdChange = (sheetId: string) =>
|
||||
const handleSheetIdChange = (sheetId: string | undefined) =>
|
||||
onOptionsChange({ ...options, sheetId })
|
||||
|
||||
const handleActionChange = (action: GoogleSheetsAction) => {
|
||||
|
||||
@@ -7,7 +7,7 @@ type Props = {
|
||||
sheets: Sheet[]
|
||||
isLoading: boolean
|
||||
sheetId?: string
|
||||
onSelectSheetId: (id: string) => void
|
||||
onSelectSheetId: (id: string | undefined) => void
|
||||
}
|
||||
|
||||
export const SheetsDropdown = ({
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useSpreadsheets } from '../../hooks/useSpreadsheets'
|
||||
type Props = {
|
||||
credentialsId: string
|
||||
spreadsheetId?: string
|
||||
onSelectSpreadsheetId: (id: string) => void
|
||||
onSelectSpreadsheetId: (id: string | undefined) => void
|
||||
}
|
||||
|
||||
export const SpreadsheetsDropdown = ({
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { featherIconsBaseProps } from '@/components/icons'
|
||||
import { Icon, IconProps } from '@chakra-ui/react'
|
||||
import React from 'react'
|
||||
|
||||
export const JumpIcon = (props: IconProps) => (
|
||||
<Icon viewBox="0 0 24 24" {...featherIconsBaseProps} {...props}>
|
||||
<polygon points="13 19 22 12 13 5 13 19"></polygon>
|
||||
<polygon points="2 19 11 12 2 5 2 19"></polygon>
|
||||
</Icon>
|
||||
)
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from 'react'
|
||||
import { Tag, Text } from '@chakra-ui/react'
|
||||
import { useTypebot } from '@/features/editor'
|
||||
import { byId, isDefined } from 'utils'
|
||||
import { JumpBlock } from 'models/features/blocks/logic/jump'
|
||||
|
||||
type Props = {
|
||||
options: JumpBlock['options']
|
||||
}
|
||||
|
||||
export const JumpNodeBody = ({ options }: Props) => {
|
||||
const { typebot } = useTypebot()
|
||||
const selectedGroup = typebot?.groups.find(byId(options.groupId))
|
||||
const blockIndex = selectedGroup?.blocks.findIndex(byId(options.blockId))
|
||||
if (!selectedGroup) return <Text color="gray.500">Configure...</Text>
|
||||
return (
|
||||
<Text>
|
||||
Jump to <Tag colorScheme="blue">{selectedGroup.title}</Tag>{' '}
|
||||
{isDefined(blockIndex) && blockIndex >= 0 ? (
|
||||
<>
|
||||
at block <Tag colorScheme="blue">{blockIndex + 1}</Tag>
|
||||
</>
|
||||
) : null}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { Select } from '@/components/inputs/Select'
|
||||
import { useTypebot } from '@/features/editor'
|
||||
import { Stack } from '@chakra-ui/react'
|
||||
import { JumpBlock } from 'models/features/blocks/logic/jump'
|
||||
import React from 'react'
|
||||
import { byId } from 'utils'
|
||||
|
||||
type Props = {
|
||||
groupId: string
|
||||
options: JumpBlock['options']
|
||||
onOptionsChange: (options: JumpBlock['options']) => void
|
||||
}
|
||||
|
||||
export const JumpSettings = ({ groupId, options, onOptionsChange }: Props) => {
|
||||
const { typebot } = useTypebot()
|
||||
|
||||
const handleGroupIdChange = (groupId?: string) =>
|
||||
onOptionsChange({ ...options, groupId })
|
||||
|
||||
const handleBlockIdChange = (blockId?: string) =>
|
||||
onOptionsChange({ ...options, blockId })
|
||||
|
||||
const currentGroupId = typebot?.groups.find(byId(groupId))?.id
|
||||
|
||||
const selectedGroup = typebot?.groups.find(byId(options.groupId))
|
||||
|
||||
if (!typebot) return null
|
||||
|
||||
return (
|
||||
<Stack spacing={4}>
|
||||
<Select
|
||||
items={typebot.groups
|
||||
.filter((group) => group.id !== currentGroupId)
|
||||
.map((group) => ({
|
||||
label: group.title,
|
||||
value: group.id,
|
||||
}))}
|
||||
selectedItem={selectedGroup?.id}
|
||||
onSelect={handleGroupIdChange}
|
||||
placeholder="Select a group"
|
||||
/>
|
||||
{selectedGroup && selectedGroup.blocks.length > 1 && (
|
||||
<Select
|
||||
selectedItem={options.blockId}
|
||||
items={selectedGroup.blocks.map((block, index) => ({
|
||||
label: `Block #${(index + 1).toString()}`,
|
||||
value: block.id,
|
||||
}))}
|
||||
onSelect={handleBlockIdChange}
|
||||
placeholder="Select a block"
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
28
apps/builder/src/features/blocks/logic/jump/jump.spec.ts
Normal file
28
apps/builder/src/features/blocks/logic/jump/jump.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import test, { expect } from '@playwright/test'
|
||||
import { importTypebotInDatabase } from 'utils/playwright/databaseActions'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { getTestAsset } from '@/test/utils/playwright'
|
||||
|
||||
test('should work as expected', async ({ page }) => {
|
||||
const typebotId = createId()
|
||||
await importTypebotInDatabase(getTestAsset('typebots/logic/jump.json'), {
|
||||
id: typebotId,
|
||||
})
|
||||
|
||||
await page.goto(`/typebots/${typebotId}/edit`)
|
||||
await page.getByText('Configure...').click()
|
||||
await page.getByPlaceholder('Select a group').click()
|
||||
await expect(page.getByRole('menuitem', { name: 'Group #2' })).toBeHidden()
|
||||
await page.getByRole('menuitem', { name: 'Group #1' }).click()
|
||||
await page.getByPlaceholder('Select a block').click()
|
||||
await page.getByRole('menuitem', { name: 'Block #2' }).click()
|
||||
await page.getByRole('button', { name: 'Preview' }).click()
|
||||
await page.getByPlaceholder('Type your answer...').fill('Hi there!')
|
||||
await page.getByRole('button', { name: 'Send' }).click()
|
||||
await expect(
|
||||
page.locator('typebot-standard').getByText('How are you?').nth(1)
|
||||
).toBeVisible()
|
||||
await expect(
|
||||
page.locator('typebot-standard').getByText('Hello this is a test!').nth(1)
|
||||
).toBeHidden()
|
||||
})
|
||||
@@ -5,7 +5,7 @@ import { Group } from 'models'
|
||||
type Props = {
|
||||
groups: Group[]
|
||||
groupId?: string
|
||||
onGroupIdSelected: (groupId: string) => void
|
||||
onGroupIdSelected: (groupId: string | undefined) => void
|
||||
isLoading?: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ type Props = {
|
||||
export const TypebotLinkForm = ({ options, onOptionsChange }: Props) => {
|
||||
const { linkedTypebots, typebot } = useTypebot()
|
||||
|
||||
const handleTypebotIdChange = (typebotId: string | 'current') =>
|
||||
const handleTypebotIdChange = (typebotId: string | 'current' | undefined) =>
|
||||
onOptionsChange({ ...options, typebotId })
|
||||
const handleGroupIdChange = (groupId: string) =>
|
||||
const handleGroupIdChange = (groupId: string | undefined) =>
|
||||
onOptionsChange({ ...options, groupId })
|
||||
|
||||
return (
|
||||
|
||||
@@ -11,7 +11,7 @@ type Props = {
|
||||
idsToExclude: string[]
|
||||
typebotId?: string | 'current'
|
||||
currentWorkspaceId: string
|
||||
onSelect: (typebotId: string | 'current') => void
|
||||
onSelect: (typebotId: string | 'current' | undefined) => void
|
||||
}
|
||||
|
||||
export const TypebotsDropdown = ({
|
||||
|
||||
Reference in New Issue
Block a user