main

mattermost/focalboard

Last updated at: 29/12/2023 09:47

addContentMenuItem.tsx

TLDR

This file, addContentMenuItem.tsx, contains a React component called AddContentMenuItem that renders a menu item for adding content. The component receives props related to the type of content, card, and coordinates. It uses the useIntl hook for internationalization and has a handler for creating blocks based on the content type. When the menu item is clicked, it performs several actions including creating a new block, updating the content order of the card, and invoking a mutator function. The AddContentMenuItem component is exported as the default export.

Methods

None

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import React from 'react'
import {useIntl} from 'react-intl'

import {BlockTypes, Block} from '../blocks/block'
import {Card} from '../blocks/card'
import mutator from '../mutator'
import octoClient from '../octoClient'
import {Utils} from '../utils'
import Menu from '../widgets/menu'

import {contentRegistry} from './content/contentRegistry'

type Props = {
    type: BlockTypes
    card: Card
    cords: {x: number, y?: number, z?: number}
}

const AddContentMenuItem = (props: Props): JSX.Element => {
    const {card, type, cords} = props
    const index = cords.x
    const intl = useIntl()

    const handler = contentRegistry.getHandler(type)
    if (!handler) {
        Utils.logError(`addContentMenu, unknown content type: ${type}`)
        return <></>
    }

    return (
        <Menu.Text
            key={type}
            id={type}
            name={handler.getDisplayText(intl)}
            icon={handler.getIcon()}
            onClick={async () => {
                const newBlock = await handler.createBlock(card.boardId, intl)
                newBlock.parentId = card.id
                newBlock.boardId = card.boardId

                const typeName = handler.getDisplayText(intl)
                const description = intl.formatMessage({id: 'ContentBlock.addElement', defaultMessage: 'add {type}'}, {type: typeName})

                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)
            }}
        />
    )
}

export default React.memo(AddContentMenuItem)