2
0

🚸 Add item duplication

Closes #545
This commit is contained in:
Baptiste Arnaud
2023-06-05 14:49:04 +02:00
parent 8822e4e7e4
commit acaa1c6223
3 changed files with 55 additions and 7 deletions

View File

@@ -24,6 +24,7 @@ type BlockWithCreatableItems = Extract<Block, { items: DraggabbleItem[] }>
export type ItemsActions = {
createItem: (item: NewItem, indices: ItemIndices) => void
duplicateItem: (indices: ItemIndices) => void
updateItem: (indices: ItemIndices, updates: Partial<Omit<Item, 'id'>>) => void
detachItemFromBlock: (indices: ItemIndices) => void
deleteItem: (indices: ItemIndices) => void
@@ -67,6 +68,44 @@ const createItem = (
}
}
const duplicateItem = (
block: Draft<BlockWithCreatableItems>,
itemIndex: number
): Item => {
const item = block.items[itemIndex]
switch (block.type) {
case LogicBlockType.CONDITION: {
const baseItem = item as ConditionItem
const newItem = {
...baseItem,
id: createId(),
content: baseItem.content ?? defaultConditionContent,
}
block.items.splice(itemIndex + 1, 0, newItem)
return newItem
}
case InputBlockType.CHOICE: {
const baseItem = item as ButtonItem
const newItem = {
...baseItem,
id: createId(),
content: baseItem.content,
}
block.items.splice(itemIndex + 1, 0, newItem)
return newItem
}
case InputBlockType.PICTURE_CHOICE: {
const baseItem = item as PictureChoiceItem
const newItem = {
...baseItem,
id: createId(),
}
block.items.splice(itemIndex + 1, 0, newItem)
return newItem
}
}
}
const itemsAction = (setTypebot: SetTypebot): ItemsActions => ({
createItem: (
item: NewItem,
@@ -94,6 +133,15 @@ const itemsAction = (setTypebot: SetTypebot): ItemsActions => ({
}
})
),
duplicateItem: ({ groupIndex, blockIndex, itemIndex }: ItemIndices) =>
setTypebot((typebot) =>
produce(typebot, (typebot) => {
const block = typebot.groups[groupIndex].blocks[
blockIndex
] as BlockWithCreatableItems
duplicateItem(block, itemIndex)
})
),
updateItem: (
{ groupIndex, blockIndex, itemIndex }: ItemIndices,
updates: Partial<Omit<Item, 'id'>>

View File

@@ -86,13 +86,12 @@ export const ItemNode = ({
transition="box-shadow 200ms, border-color 200ms"
rounded="md"
bg={bg}
borderWidth={isContextMenuOpened || isPreviewing ? '2px' : '1px'}
borderWidth={1}
borderColor={
isContextMenuOpened || isPreviewing
? previewingBorderColor
: borderColor
}
margin={isContextMenuOpened || isPreviewing ? '-1px' : 0}
w="full"
>
<ItemNodeContent

View File

@@ -1,5 +1,5 @@
import { MenuList, MenuItem } from '@chakra-ui/react'
import { TrashIcon } from '@/components/icons'
import { CopyIcon, TrashIcon } from '@/components/icons'
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
import { ItemIndices } from '@typebot.io/schemas'
@@ -7,13 +7,14 @@ type Props = {
indices: ItemIndices
}
export const ItemNodeContextMenu = ({ indices }: Props) => {
const { deleteItem } = useTypebot()
const handleDeleteClick = () => deleteItem(indices)
const { deleteItem, duplicateItem } = useTypebot()
return (
<MenuList>
<MenuItem icon={<TrashIcon />} onClick={handleDeleteClick}>
<MenuItem icon={<CopyIcon />} onClick={() => duplicateItem(indices)}>
Duplicate
</MenuItem>
<MenuItem icon={<TrashIcon />} onClick={() => deleteItem(indices)}>
Delete
</MenuItem>
</MenuList>