// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import React from 'react' import {FormattedMessage} from 'react-intl' import {Constants} from '../constants' import {BlockIcons} from '../blockIcons' import {IPropertyTemplate} from '../blocks/board' import {Card, MutableCard} from '../blocks/card' import {BoardTree} from '../viewModel/boardTree' import mutator from '../mutator' import {Utils} from '../utils' import MenuWrapper from '../widgets/menuWrapper' import {CardDialog} from './cardDialog' import RootPortal from './rootPortal' import {TableRow} from './tableRow' import ViewHeader from './viewHeader' import ViewTitle from './viewTitle' import TableHeaderMenu from './tableHeaderMenu' import './tableComponent.scss' import {HorizontalGrip} from './horizontalGrip' import {MutableBoardView} from '../blocks/boardView' type Props = { boardTree?: BoardTree showView: (id: string) => void setSearchText: (text: string) => void } type State = { shownCard?: Card } class TableComponent extends React.Component { private draggedHeaderTemplate: IPropertyTemplate private cardIdToRowMap = new Map>() private cardIdToFocusOnRender: string state: State = {} shouldComponentUpdate(): boolean { return true } render(): JSX.Element { const {boardTree, showView} = this.props if (!boardTree || !boardTree.board) { return (
) } const {board, cards, activeView} = boardTree const titleRef = React.createRef() this.cardIdToRowMap.clear() return (
{this.state.shownCard && this.setState({shownCard: undefined})} /> }
{/* Main content */}
{/* Headers */}
{ const originalWidth = this.columnWidth(Constants.titleColumnId) const newWidth = Math.max(Constants.minColumnWidth, originalWidth + offset) titleRef.current.style.width = `${newWidth}px` }} onDragEnd={(offset) => { Utils.log(`onDragEnd offset: ${offset}`) const originalWidth = this.columnWidth(Constants.titleColumnId) const newWidth = Math.max(Constants.minColumnWidth, originalWidth + offset) titleRef.current.style.width = `${newWidth}px` const columnWidths = {...activeView.columnWidths} if (newWidth !== columnWidths[Constants.titleColumnId]) { columnWidths[Constants.titleColumnId] = newWidth const newView = new MutableBoardView(activeView) newView.columnWidths = columnWidths mutator.updateBlock(newView, activeView, 'resize column') } }} />
{/* Table header row */} {board.cardProperties. filter((template) => activeView.visiblePropertyIds.includes(template.id)). map((template) => { const headerRef = React.createRef() return (
{ e.preventDefault(); (e.target as HTMLElement).classList.add('dragover') }} onDragEnter={(e) => { e.preventDefault(); (e.target as HTMLElement).classList.add('dragover') }} onDragLeave={(e) => { e.preventDefault(); (e.target as HTMLElement).classList.remove('dragover') }} onDrop={(e) => { e.preventDefault(); (e.target as HTMLElement).classList.remove('dragover'); this.onDropToColumn(template) }} >
{ this.draggedHeaderTemplate = template }} onDragEnd={() => { this.draggedHeaderTemplate = undefined }} >{template.name}
{ const originalWidth = this.columnWidth(template.id) const newWidth = Math.max(Constants.minColumnWidth, originalWidth + offset) headerRef.current.style.width = `${newWidth}px` }} onDragEnd={(offset) => { Utils.log(`onDragEnd offset: ${offset}`) const originalWidth = this.columnWidth(template.id) const newWidth = Math.max(Constants.minColumnWidth, originalWidth + offset) headerRef.current.style.width = `${newWidth}px` const columnWidths = {...activeView.columnWidths} if (newWidth !== columnWidths[template.id]) { columnWidths[template.id] = newWidth const newView = new MutableBoardView(activeView) newView.columnWidths = columnWidths mutator.updateBlock(newView, activeView, 'resize column') } }} />
) })}
{/* Rows, one per card */} {cards.map((card) => { const openButonRef = React.createRef() const tableRowRef = React.createRef() let focusOnMount = false if (this.cardIdToFocusOnRender && this.cardIdToFocusOnRender === card.id) { this.cardIdToFocusOnRender = undefined focusOnMount = true } const tableRow = ( { console.log('WORKING') if (cards.length > 0 && cards[cards.length - 1] === card) { this.addCard(false) } console.log('STILL WORKING') }} />) this.cardIdToRowMap.set(card.id, tableRowRef) return tableRow })} {/* Add New row */}
{ this.addCard() }} >
) } private columnWidth(templateId: string): number { return Math.max(Constants.minColumnWidth, this.props.boardTree?.activeView?.columnWidths[templateId] || 0) } private addCard = async (show = false) => { const {boardTree} = this.props const card = new MutableCard() card.parentId = boardTree.board.id card.icon = BlockIcons.shared.randomIcon() await mutator.insertBlock( card, 'add card', async () => { if (show) { this.setState({shownCard: card}) } else { // Focus on this card's title inline on next render this.cardIdToFocusOnRender = card.id } }, ) } private async onDropToColumn(template: IPropertyTemplate) { const {draggedHeaderTemplate} = this if (!draggedHeaderTemplate) { return } const {boardTree} = this.props const {board} = boardTree Utils.assertValue(mutator) Utils.assertValue(boardTree) Utils.log(`ondrop. Source column: ${draggedHeaderTemplate.name}, dest column: ${template.name}`) // Move template to new index const destIndex = template ? board.cardProperties.indexOf(template) : 0 await mutator.changePropertyTemplateOrder(board, draggedHeaderTemplate, destIndex) } } export {TableComponent}