Fixing redo on card contents (#2831)
* Fixing redo on card contents * Fixing tests
This commit is contained in:
parent
3e6383b475
commit
340fcf20f1
5 changed files with 60 additions and 29 deletions
|
@ -67,7 +67,7 @@ describe('components/addContentMenuItem', () => {
|
|||
expect(container).toMatchSnapshot()
|
||||
const buttonElement = screen.getByRole('button', {name: 'text'})
|
||||
userEvent.click(buttonElement)
|
||||
await waitFor(() => expect(mockedMutator.performAsUndoGroup).toBeCalled())
|
||||
await waitFor(() => expect(mockedMutator.insertBlock).toBeCalled())
|
||||
})
|
||||
|
||||
test('return a checkbox menu item', async () => {
|
||||
|
@ -83,7 +83,7 @@ describe('components/addContentMenuItem', () => {
|
|||
expect(container).toMatchSnapshot()
|
||||
const buttonElement = screen.getByRole('button', {name: 'checkbox'})
|
||||
userEvent.click(buttonElement)
|
||||
await waitFor(() => expect(mockedMutator.performAsUndoGroup).toBeCalled())
|
||||
await waitFor(() => expect(mockedMutator.insertBlock).toBeCalled())
|
||||
})
|
||||
|
||||
test('return a divider menu item', async () => {
|
||||
|
@ -99,7 +99,7 @@ describe('components/addContentMenuItem', () => {
|
|||
expect(container).toMatchSnapshot()
|
||||
const buttonElement = screen.getByRole('button', {name: 'divider'})
|
||||
userEvent.click(buttonElement)
|
||||
await waitFor(() => expect(mockedMutator.performAsUndoGroup).toBeCalled())
|
||||
await waitFor(() => expect(mockedMutator.insertBlock).toBeCalled())
|
||||
})
|
||||
|
||||
test('return an error and empty element from unknown type', () => {
|
||||
|
|
|
@ -6,7 +6,9 @@ import {useIntl} from 'react-intl'
|
|||
|
||||
import {BlockTypes} from '../blocks/block'
|
||||
import {Card} from '../blocks/card'
|
||||
import {Block} from '../blocks/block'
|
||||
import mutator from '../mutator'
|
||||
import octoClient from '../octoClient'
|
||||
import {Utils} from '../utils'
|
||||
import Menu from '../widgets/menu'
|
||||
|
||||
|
@ -21,7 +23,6 @@ type Props = {
|
|||
const AddContentMenuItem = (props:Props): JSX.Element => {
|
||||
const {card, type, cords} = props
|
||||
const index = cords.x
|
||||
const contentOrder = card.fields.contentOrder.slice()
|
||||
const intl = useIntl()
|
||||
|
||||
const handler = contentRegistry.getHandler(type)
|
||||
|
@ -43,11 +44,19 @@ const AddContentMenuItem = (props:Props): JSX.Element => {
|
|||
|
||||
const typeName = handler.getDisplayText(intl)
|
||||
const description = intl.formatMessage({id: 'ContentBlock.addElement', defaultMessage: 'add {type}'}, {type: typeName})
|
||||
mutator.performAsUndoGroup(async () => {
|
||||
const insertedBlock = await mutator.insertBlock(newBlock.boardId, newBlock, description)
|
||||
contentOrder.splice(index, 0, insertedBlock.id)
|
||||
await mutator.changeCardContentOrder(card.boardId, card.id, card.fields.contentOrder, contentOrder, description)
|
||||
})
|
||||
|
||||
const afterRedo = async (nb: Block) => {
|
||||
const contentOrder = card.fields.contentOrder.slice()
|
||||
contentOrder.splice(index, 0, nb.id)
|
||||
await octoClient.patchBlock(card.boardId, card.id, {updatedFields: {contentOrder}})
|
||||
}
|
||||
|
||||
const beforeUndo = async () => {
|
||||
const contentOrder = card.fields.contentOrder.slice()
|
||||
await octoClient.patchBlock(card.boardId, card.id, {updatedFields: {contentOrder}})
|
||||
}
|
||||
|
||||
await mutator.insertBlock(newBlock.boardId, newBlock, description, afterRedo, beforeUndo)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -6,7 +6,9 @@ import {useIntl, IntlShape} from 'react-intl'
|
|||
import {IContentBlockWithCords, ContentBlock as ContentBlockType} from '../../blocks/contentBlock'
|
||||
import {Card} from '../../blocks/card'
|
||||
import {createTextBlock} from '../../blocks/textBlock'
|
||||
import {Block} from '../../blocks/block'
|
||||
import mutator from '../../mutator'
|
||||
import octoClient from '../../octoClient'
|
||||
import {useSortableWithGrip} from '../../hooks/sortable'
|
||||
|
||||
import ContentBlock from '../contentBlock'
|
||||
|
@ -25,19 +27,26 @@ type Props = {
|
|||
readonly: boolean
|
||||
}
|
||||
|
||||
function addTextBlock(card: Card, intl: IntlShape, text: string): void {
|
||||
async function addTextBlock(card: Card, intl: IntlShape, text: string): Promise<Block> {
|
||||
const block = createTextBlock()
|
||||
block.parentId = card.id
|
||||
block.boardId = card.boardId
|
||||
block.title = text
|
||||
|
||||
mutator.performAsUndoGroup(async () => {
|
||||
const description = intl.formatMessage({id: 'CardDetail.addCardText', defaultMessage: 'add card text'})
|
||||
const insertedBlock = await mutator.insertBlock(block.boardId, block, description)
|
||||
|
||||
const afterRedo = async (newBlock: Block) => {
|
||||
const contentOrder = card.fields.contentOrder.slice()
|
||||
contentOrder.push(insertedBlock.id)
|
||||
await mutator.changeCardContentOrder(card.boardId, card.id, card.fields.contentOrder, contentOrder, description)
|
||||
})
|
||||
contentOrder.push(newBlock.id)
|
||||
await octoClient.patchBlock(card.boardId, card.id, {updatedFields: {contentOrder}})
|
||||
}
|
||||
|
||||
const beforeUndo = async () => {
|
||||
const contentOrder = card.fields.contentOrder.slice()
|
||||
await octoClient.patchBlock(card.boardId, card.id, {updatedFields: {contentOrder}})
|
||||
}
|
||||
|
||||
return mutator.insertBlock(block.boardId, block, description, afterRedo, beforeUndo)
|
||||
}
|
||||
|
||||
function moveBlock(card: Card, srcBlock: IContentBlockWithCords, dstBlock: IContentBlockWithCords, intl: IntlShape, moveTo: Position): void {
|
||||
|
|
|
@ -7,6 +7,7 @@ import {useIntl} from 'react-intl'
|
|||
import {Block} from '../../blocks/block'
|
||||
import {Card} from '../../blocks/card'
|
||||
import {ContentHandler} from '../content/contentRegistry'
|
||||
import octoClient from '../../octoClient'
|
||||
import mutator from '../../mutator'
|
||||
|
||||
export type AddedBlock = {
|
||||
|
@ -50,14 +51,20 @@ export const CardDetailProvider = (props: CardDetailProps): ReactElement => {
|
|||
const typeName = handler.getDisplayText(intl)
|
||||
const description = intl.formatMessage({id: 'ContentBlock.addElement', defaultMessage: 'add {type}'}, {type: typeName})
|
||||
await mutator.performAsUndoGroup(async () => {
|
||||
const insertedBlock = await mutator.insertBlock(block.boardId, block, description)
|
||||
|
||||
const afterRedo = async (newBlock: Block) => {
|
||||
const contentOrder = card.fields.contentOrder.slice()
|
||||
contentOrder.splice(index, 0, insertedBlock.id)
|
||||
setLastAddedBlock({
|
||||
id: insertedBlock.id,
|
||||
autoAdded: auto,
|
||||
})
|
||||
await mutator.changeCardContentOrder(card.boardId, card.id, card.fields.contentOrder, contentOrder, description)
|
||||
contentOrder.splice(index, 0, newBlock.id)
|
||||
await octoClient.patchBlock(card.boardId, card.id, {updatedFields: {contentOrder}})
|
||||
}
|
||||
|
||||
const beforeUndo = async () => {
|
||||
const contentOrder = card.fields.contentOrder.slice()
|
||||
await octoClient.patchBlock(card.boardId, card.id, {updatedFields: {contentOrder}})
|
||||
}
|
||||
|
||||
const insertedBlock = await mutator.insertBlock(block.boardId, block, description, afterRedo, beforeUndo)
|
||||
setLastAddedBlock({id: insertedBlock.id, autoAdded: auto})
|
||||
})
|
||||
}, [card.boardId, card.id, card.fields.contentOrder])
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import {useIntl} from 'react-intl'
|
|||
|
||||
import {ImageBlock, createImageBlock} from '../../blocks/imageBlock'
|
||||
import {sendFlashMessage} from '../flashMessages'
|
||||
import {Block} from '../../blocks/block'
|
||||
import octoClient from '../../octoClient'
|
||||
import mutator from '../../mutator'
|
||||
|
||||
|
@ -45,13 +46,18 @@ export default function useImagePaste(boardId: string, cardId: string, contentOr
|
|||
sendFlashMessage({content: intl.formatMessage({id: 'imagePaste.upload-failed', defaultMessage: 'Some files not uploaded. File size limit reached'}), severity: 'normal'})
|
||||
}
|
||||
|
||||
mutator.performAsUndoGroup(async () => {
|
||||
const newContentBlocks = await mutator.insertBlocks(boardId, blocksToInsert, 'pasted images')
|
||||
const afterRedo = async (newBlocks: Block[]) => {
|
||||
const newContentOrder = JSON.parse(JSON.stringify(contentOrder))
|
||||
newContentOrder.push(...newContentBlocks.map((b: ImageBlock) => b.id))
|
||||
newContentOrder.push(...newBlocks.map((b: Block) => b.id))
|
||||
await octoClient.patchBlock(boardId, cardId, {updatedFields: {contentOrder: newContentOrder}})
|
||||
}
|
||||
|
||||
await mutator.changeCardContentOrder(boardId, cardId, contentOrder, newContentOrder, 'paste image')
|
||||
})
|
||||
const beforeUndo = async () => {
|
||||
const newContentOrder = JSON.parse(JSON.stringify(contentOrder))
|
||||
await octoClient.patchBlock(boardId, cardId, {updatedFields: {contentOrder: newContentOrder}})
|
||||
}
|
||||
|
||||
await mutator.insertBlocks(boardId, blocksToInsert, 'pasted images', afterRedo, beforeUndo)
|
||||
}, [cardId, contentOrder, boardId])
|
||||
|
||||
const onDrop = useCallback((event: DragEvent): void => {
|
||||
|
|
Loading…
Reference in a new issue