🚸 (buttons) Show collected variable in buttons block preview
This commit is contained in:
@ -51,6 +51,9 @@ test.describe.parallel('Buttons input block', () => {
|
||||
await page.click('[data-testid="block2-icon"]')
|
||||
await page.click('text=Multiple choice?')
|
||||
await page.fill('#button', 'Go')
|
||||
await page.getByPlaceholder('Select a variable').click()
|
||||
await page.getByText('var1').click()
|
||||
await expect(page.getByText('Collectsvar1')).toBeVisible()
|
||||
await page.click('[data-testid="block2-icon"]')
|
||||
|
||||
await page.locator('text=Item 1').hover()
|
||||
|
@ -4,39 +4,72 @@ import {
|
||||
BlockWithItems,
|
||||
defaultConditionContent,
|
||||
ItemType,
|
||||
Block,
|
||||
LogicBlockType,
|
||||
InputBlockType,
|
||||
} from 'models'
|
||||
import { SetTypebot } from '../TypebotProvider'
|
||||
import produce from 'immer'
|
||||
import { cleanUpEdgeDraft } from './edges'
|
||||
import { byId, blockHasItems } from 'utils'
|
||||
import cuid from 'cuid'
|
||||
import { WritableDraft } from 'immer/dist/types/types-external'
|
||||
|
||||
type NewItem = Pick<Item, 'blockId' | 'outgoingEdgeId' | 'type'> & Partial<Item>
|
||||
|
||||
export type ItemsActions = {
|
||||
createItem: (item: Item | Omit<Item, 'id'>, indices: ItemIndices) => void
|
||||
createItem: (item: NewItem, indices: ItemIndices) => void
|
||||
updateItem: (indices: ItemIndices, updates: Partial<Omit<Item, 'id'>>) => void
|
||||
detachItemFromBlock: (indices: ItemIndices) => void
|
||||
deleteItem: (indices: ItemIndices) => void
|
||||
}
|
||||
|
||||
const createItem = (
|
||||
block: WritableDraft<Block>,
|
||||
item: NewItem,
|
||||
itemIndex: number
|
||||
) => {
|
||||
switch (block.type) {
|
||||
case LogicBlockType.CONDITION: {
|
||||
if (item.type === ItemType.CONDITION) {
|
||||
const newItem = {
|
||||
...item,
|
||||
id: 'id' in item && item.id ? item.id : cuid(),
|
||||
content: item.content ?? defaultConditionContent,
|
||||
}
|
||||
block.items.splice(itemIndex, 0, newItem)
|
||||
return newItem
|
||||
}
|
||||
break
|
||||
}
|
||||
case InputBlockType.CHOICE: {
|
||||
if (item.type === ItemType.BUTTON) {
|
||||
const newItem = {
|
||||
...item,
|
||||
id: 'id' in item && item.id ? item.id : cuid(),
|
||||
content: item.content,
|
||||
}
|
||||
block.items.splice(itemIndex, 0, newItem)
|
||||
return newItem
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const itemsAction = (setTypebot: SetTypebot): ItemsActions => ({
|
||||
createItem: (
|
||||
item: Item | Omit<Item, 'id'>,
|
||||
item: NewItem,
|
||||
{ groupIndex, blockIndex, itemIndex }: ItemIndices
|
||||
) =>
|
||||
setTypebot((typebot) =>
|
||||
produce(typebot, (typebot) => {
|
||||
const block = typebot.groups[groupIndex].blocks[
|
||||
blockIndex
|
||||
] as BlockWithItems
|
||||
const block = typebot.groups[groupIndex].blocks[blockIndex]
|
||||
|
||||
const newItem = createItem(block, item, itemIndex)
|
||||
|
||||
if (!newItem) return
|
||||
|
||||
const newItem = {
|
||||
id: 'id' in item ? item.id : cuid(),
|
||||
content:
|
||||
item.type === ItemType.CONDITION
|
||||
? defaultConditionContent
|
||||
: undefined,
|
||||
...item,
|
||||
} as Item
|
||||
if (item.outgoingEdgeId) {
|
||||
const edgeIndex = typebot.edges.findIndex(byId(item.outgoingEdgeId))
|
||||
edgeIndex !== -1
|
||||
@ -47,7 +80,6 @@ const itemsAction = (setTypebot: SetTypebot): ItemsActions => ({
|
||||
})
|
||||
: (newItem.outgoingEdgeId = undefined)
|
||||
}
|
||||
block.items.splice(itemIndex, 0, newItem)
|
||||
})
|
||||
),
|
||||
updateItem: (
|
||||
|
@ -1,7 +1,9 @@
|
||||
import {
|
||||
Flex,
|
||||
HStack,
|
||||
Portal,
|
||||
Stack,
|
||||
Tag,
|
||||
Text,
|
||||
useColorModeValue,
|
||||
useEventListener,
|
||||
@ -13,7 +15,13 @@ import {
|
||||
useGraph,
|
||||
} from '../../../providers'
|
||||
import { useTypebot } from '@/features/editor'
|
||||
import { BlockIndices, BlockWithItems, LogicBlockType, Item } from 'models'
|
||||
import {
|
||||
BlockIndices,
|
||||
BlockWithItems,
|
||||
LogicBlockType,
|
||||
Item,
|
||||
Variable,
|
||||
} from 'models'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { ItemNode } from './ItemNode'
|
||||
import { SourceEndpoint } from '../../Endpoints'
|
||||
@ -127,8 +135,16 @@ export const ItemNodesList = ({
|
||||
elem && (placeholderRefs.current[idx] = elem)
|
||||
}
|
||||
|
||||
const collectedVariableId = 'options' in block && block.options.variableId
|
||||
|
||||
return (
|
||||
<Stack flex={1} spacing={1} maxW="full" onClick={stopPropagating}>
|
||||
{collectedVariableId && (
|
||||
<CollectVariableLabel
|
||||
variableId={collectedVariableId}
|
||||
variables={typebot?.variables ?? []}
|
||||
/>
|
||||
)}
|
||||
<PlaceholderNode
|
||||
isVisible={showPlaceholders}
|
||||
isExpanded={expandedPlaceholderIndex === 0}
|
||||
@ -202,3 +218,20 @@ const DefaultItemNode = ({ block }: { block: BlockWithItems }) => {
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
const CollectVariableLabel = ({
|
||||
variableId,
|
||||
variables,
|
||||
}: {
|
||||
variableId: string
|
||||
variables: Variable[]
|
||||
}) => (
|
||||
<HStack fontStyle="italic" spacing={1}>
|
||||
<Text fontSize="sm" color={useColorModeValue('gray.600', 'gray.400')}>
|
||||
Collects
|
||||
</Text>
|
||||
<Tag bg="orange.400" color="white" size="sm">
|
||||
{variables.find((variable) => variable.id === variableId)?.name}
|
||||
</Tag>
|
||||
</HStack>
|
||||
)
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
LogicBlockOptions,
|
||||
} from '.'
|
||||
import { BubbleBlock, bubbleBlockSchema } from './bubbles'
|
||||
import { InputBlock, inputBlockSchema } from './inputs'
|
||||
import { ChoiceInputBlock, InputBlock, inputBlockSchema } from './inputs'
|
||||
import { IntegrationBlock, integrationBlockSchema } from './integrations'
|
||||
import { ConditionBlock, LogicBlock, logicBlockSchema } from './logic'
|
||||
import { z } from 'zod'
|
||||
@ -51,7 +51,7 @@ export type BlockOptions =
|
||||
| LogicBlockOptions
|
||||
| IntegrationBlockOptions
|
||||
|
||||
export type BlockWithItems = Omit<Block, 'items'> & { items: Item[] }
|
||||
export type BlockWithItems = ConditionBlock | ChoiceInputBlock
|
||||
|
||||
export type BlockBase = z.infer<typeof blockBaseSchema>
|
||||
|
||||
|
@ -43,7 +43,6 @@ export const conditionBlockSchema = blockBaseSchema.and(
|
||||
z.object({
|
||||
type: z.enum([LogicBlockType.CONDITION]),
|
||||
items: z.array(conditionItemSchema),
|
||||
options: z.object({}),
|
||||
})
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user