main

mattermost/focalboard

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

gallery.tsx

TLDR

The gallery.tsx file contains the implementation of a React component called Gallery that renders a gallery of cards. It allows users to add new cards, rearrange the order of cards, and perform various actions on individual cards.

Methods

The gallery.tsx file does not contain any methods.

Classes

The gallery.tsx file does not contain any classes.

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useMemo, useCallback} from 'react'
import {FormattedMessage} from 'react-intl'

import {Constants, Permission} from '../../constants'
import HiddenCardCount from '../../components/hiddenCardCount/hiddenCardCount'

import {Card} from '../../blocks/card'
import {Board, IPropertyTemplate} from '../../blocks/board'
import {BoardView} from '../../blocks/boardView'
import mutator from '../../mutator'
import {Utils} from '../../utils'

import BoardPermissionGate from '../permissions/boardPermissionGate'

import './gallery.scss'
import GalleryCard from './galleryCard'

type Props = {
    board: Board
    cards: Card[]
    activeView: BoardView
    readonly: boolean
    addCard: (show: boolean) => Promise<void>
    selectedCardIds: string[]
    onCardClicked: (e: React.MouseEvent, card: Card) => void
    hiddenCardsCount: number
    showHiddenCardCountNotification: (show: boolean) => void
}

const Gallery = (props: Props): JSX.Element => {
    const {activeView, board, cards, hiddenCardsCount} = props
    const visiblePropertyTemplates = useMemo(() => {
        return board.cardProperties.filter(
            (template: IPropertyTemplate) => activeView.fields.visiblePropertyIds.includes(template.id),
        )
    }, [board.cardProperties, activeView.fields.visiblePropertyIds])

    const isManualSort = activeView.fields.sortOptions.length === 0

    const onDropToCard = useCallback((srcCard: Card, dstCard: Card) => {
        Utils.log(`onDropToCard: ${dstCard.title}`)
        const {selectedCardIds} = props

        const draggedCardIds = Array.from(new Set(selectedCardIds).add(srcCard.id))
        const description = draggedCardIds.length > 1 ? `drag ${draggedCardIds.length} cards` : 'drag card'

        // Update dstCard order
        let cardOrder = Array.from(new Set([...activeView.fields.cardOrder, ...cards.map((o) => o.id)]))
        const isDraggingDown = cardOrder.indexOf(srcCard.id) <= cardOrder.indexOf(dstCard.id)
        cardOrder = cardOrder.filter((id) => !draggedCardIds.includes(id))
        let destIndex = cardOrder.indexOf(dstCard.id)
        if (isDraggingDown) {
            destIndex += 1
        }
        cardOrder.splice(destIndex, 0, ...draggedCardIds)

        mutator.performAsUndoGroup(async () => {
            await mutator.changeViewCardOrder(board.id, activeView.id, activeView.fields.cardOrder, cardOrder, description)
        })
    }, [cards.map((o) => o.id).join(','), board.id, activeView.id, activeView.fields.cardOrder, props.selectedCardIds])

    const visibleTitle = activeView.fields.visiblePropertyIds.includes(Constants.titleColumnId)
    const visibleBadges = activeView.fields.visiblePropertyIds.includes(Constants.badgesColumnId)

    return (

        <div className='Gallery'>
            {cards.filter((c) => c.boardId === board.id).map((card) => {
                return (
                    <GalleryCard
                        key={card.id + card.updateAt}
                        card={card}
                        board={board}
                        onClick={props.onCardClicked}
                        visiblePropertyTemplates={visiblePropertyTemplates}
                        visibleTitle={visibleTitle}
                        visibleBadges={visibleBadges}
                        isSelected={props.selectedCardIds.includes(card.id)}
                        readonly={props.readonly}
                        onDrop={onDropToCard}
                        isManualSort={isManualSort}
                    />
                )
            })}

            {/* Add New row */}

            {!props.readonly &&
                <BoardPermissionGate permissions={[Permission.ManageBoardCards]}>
                    <div
                        className='octo-gallery-new'
                        onClick={() => {
                            props.addCard(true)
                        }}
                    >
                        <FormattedMessage
                            id='TableComponent.plus-new'
                            defaultMessage='+ New'
                        />
                    </div>
                </BoardPermissionGate>
            }
            {hiddenCardsCount > 0 &&
            <div className='gallery-hidden-cards'>
                <HiddenCardCount
                    hiddenCardsCount={hiddenCardsCount}
                    showHiddenCardNotification={props.showHiddenCardCountNotification}
                />
            </div>}
        </div>
    )
}

export default Gallery