Skip to content

Commit

Permalink
🚸 Add item duplication
Browse files Browse the repository at this point in the history
Closes #545
  • Loading branch information
baptisteArno committed Jun 5, 2023
1 parent 8822e4e commit acaa1c6
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 7 deletions.
48 changes: 48 additions & 0 deletions apps/builder/src/features/editor/providers/typebotActions/items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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'>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
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'

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>
Expand Down

0 comments on commit acaa1c6

Please sign in to comment.