focalboard/webapp/src/components/boardCard.tsx

110 lines
3.5 KiB
TypeScript
Raw Normal View History

2020-10-20 21:50:53 +02:00
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
2020-10-20 21:52:56 +02:00
import React from 'react'
import {MutableBlock} from '../blocks/block'
2020-10-20 21:50:53 +02:00
2020-10-20 21:52:56 +02:00
import {IPropertyTemplate} from '../blocks/board'
import {Card} from '../blocks/card'
import {Menu} from '../menu'
import mutator from '../mutator'
import {OctoUtils} from '../octoUtils'
import {Utils} from '../utils'
2020-10-08 18:21:27 +02:00
type BoardCardProps = {
2020-10-20 21:50:53 +02:00
card: Card
visiblePropertyTemplates: IPropertyTemplate[]
isSelected: boolean
2020-10-20 21:50:53 +02:00
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void
onDragStart?: (e: React.DragEvent<HTMLDivElement>) => void
onDragEnd?: (e: React.DragEvent<HTMLDivElement>) => void
2020-10-08 18:21:27 +02:00
}
type BoardCardState = {
2020-10-20 21:50:53 +02:00
isDragged?: boolean
2020-10-08 18:21:27 +02:00
}
class BoardCard extends React.Component<BoardCardProps, BoardCardState> {
2020-10-20 21:50:53 +02:00
constructor(props: BoardCardProps) {
super(props)
this.state = {}
}
2020-10-08 18:21:27 +02:00
2020-10-20 21:50:53 +02:00
render() {
const {card} = this.props
const optionsButtonRef = React.createRef<HTMLDivElement>()
const visiblePropertyTemplates = this.props.visiblePropertyTemplates || []
const className = this.props.isSelected ? 'octo-board-card selected' : 'octo-board-card'
2020-10-20 21:50:53 +02:00
const element =
(<div
className={className}
2020-10-20 21:50:53 +02:00
draggable={true}
style={{opacity: this.state.isDragged ? 0.5 : 1}}
onClick={this.props.onClick}
onDragStart={(e) => {
this.setState({isDragged: true}); this.props.onDragStart(e)
}}
onDragEnd={(e) => {
this.setState({isDragged: false}); this.props.onDragEnd(e)
}}
2020-10-08 18:21:27 +02:00
2020-10-20 21:50:53 +02:00
onMouseOver={() => {
optionsButtonRef.current.style.display = null
}}
onMouseLeave={() => {
2020-10-20 21:52:56 +02:00
optionsButtonRef.current.style.display = 'none'
2020-10-20 21:50:53 +02:00
}}
>
<div
ref={optionsButtonRef}
className='octo-hoverbutton square'
style={{display: 'none'}}
onClick={(e) => {
this.showOptionsMenu(e)
}}
><div className='imageOptions'/></div>
2020-10-08 18:21:27 +02:00
2020-10-20 21:50:53 +02:00
<div className='octo-icontitle'>
{ card.icon ? <div className='octo-icon'>{card.icon}</div> : undefined }
<div key='__title'>{card.title || 'Untitled'}</div>
</div>
{visiblePropertyTemplates.map((template) => {
return OctoUtils.propertyValueReadonlyElement(card, template, '')
})}
2020-10-20 21:50:53 +02:00
</div>)
2020-10-08 18:21:27 +02:00
2020-10-20 21:50:53 +02:00
return element
}
2020-10-08 18:21:27 +02:00
2020-10-20 21:50:53 +02:00
private showOptionsMenu(e: React.MouseEvent) {
const {card} = this.props
2020-10-08 18:21:27 +02:00
2020-10-20 21:50:53 +02:00
e.stopPropagation()
2020-10-08 18:21:27 +02:00
2020-10-20 21:50:53 +02:00
Menu.shared.options = [
{id: 'delete', name: 'Delete'},
{id: 'duplicate', name: 'Duplicate'},
]
Menu.shared.onMenuClicked = (id) => {
switch (id) {
case 'delete': {
mutator.deleteBlock(card, 'delete card')
2020-10-20 21:52:56 +02:00
break
2020-10-20 21:50:53 +02:00
}
case 'duplicate': {
2020-10-21 03:28:55 +02:00
const newCard = MutableBlock.duplicate(card)
2020-10-20 21:50:53 +02:00
mutator.insertBlock(newCard, 'duplicate card')
2020-10-20 21:52:56 +02:00
break
2020-10-20 21:50:53 +02:00
}
default: {
Utils.assertFailure(`Unhandled menu id: ${id}`)
}
}
}
Menu.shared.showAtElement(e.target as HTMLElement)
}
2020-10-08 18:21:27 +02:00
}
2020-10-20 21:50:53 +02:00
export {BoardCard}