cardDetailContext.tsx
TLDR
The cardDetailContext.tsx
file in the Demo Projects project is a TypeScript file that contains the implementation of a context provider and hooks for managing the details of a card.
Methods
useCardDetailContext
This method is a custom hook that allows components to access the card detail context. It returns the current card detail context value. If the context is not available, it throws an error.
addBlock
This method is responsible for adding a new block to the card details. It takes parameters for the content handler, index, and auto addition flag. It creates a new block using the content handler, updates its parent and board IDs, and performs the necessary mutations using the mutator
module. It also updates the last added block state.
deleteBlock
This method is responsible for deleting a block from the card details. It takes parameters for the block and index. It removes the block from the content order of the card and performs the necessary mutations using the mutator
module.
Classes
None
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {createContext, ReactElement, ReactNode, useContext, useMemo, useState, useCallback} from 'react'
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 = {
id: string
autoAdded: boolean
}
export type CardDetailContextType = {
card: Card
lastAddedBlock: AddedBlock
addBlock: (handler: ContentHandler, index: number, auto: boolean) => void
deleteBlock: (block: Block, index: number) => void
}
export const CardDetailContext = createContext<CardDetailContextType | null>(null)
export function useCardDetailContext(): CardDetailContextType {
const cardDetailContext = useContext(CardDetailContext)
if (!cardDetailContext) {
throw new Error('CardDetailContext is not available!')
}
return cardDetailContext
}
type CardDetailProps = {
card: Card
children: ReactNode
}
export const CardDetailProvider = (props: CardDetailProps): ReactElement => {
const intl = useIntl()
const [lastAddedBlock, setLastAddedBlock] = useState<AddedBlock>({
id: '',
autoAdded: false,
})
const {card} = props
const addBlock = useCallback(async (handler: ContentHandler, index: number, auto: boolean) => {
const block = await handler.createBlock(card.boardId, intl)
block.parentId = card.id
block.boardId = card.boardId
const typeName = handler.getDisplayText(intl)
const description = intl.formatMessage({id: 'ContentBlock.addElement', defaultMessage: 'add {type}'}, {type: typeName})
await mutator.performAsUndoGroup(async () => {
const afterRedo = async (newBlock: Block) => {
const contentOrder = card.fields.contentOrder.slice()
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])
const deleteBlock = useCallback(async (block: Block, index: number) => {
const contentOrder = card.fields.contentOrder.slice()
contentOrder.splice(index, 1)
const description = intl.formatMessage({id: 'ContentBlock.DeleteAction', defaultMessage: 'delete'})
await mutator.performAsUndoGroup(async () => {
await mutator.deleteBlock(block, description)
await mutator.changeCardContentOrder(card.boardId, card.id, card.fields.contentOrder, contentOrder, description)
})
}, [card.boardId, card.id, card.fields.contentOrder])
const contextValue = useMemo(() => ({
card,
lastAddedBlock,
addBlock,
deleteBlock,
}), [card, lastAddedBlock, addBlock, deleteBlock])
return (
<CardDetailContext.Provider value={contextValue}>
{props.children}
</CardDetailContext.Provider>
)
}