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'
|
2020-10-25 09:47:50 +01:00
|
|
|
import {injectIntl, IntlShape} from 'react-intl'
|
2020-10-22 00:03:12 +02:00
|
|
|
|
2020-10-20 21:52:56 +02:00
|
|
|
import {IPropertyTemplate} from '../blocks/board'
|
|
|
|
import {Card} from '../blocks/card'
|
|
|
|
import mutator from '../mutator'
|
2020-11-13 03:48:59 +01:00
|
|
|
import IconButton from '../widgets/buttons/iconButton'
|
2020-10-30 16:49:19 +01:00
|
|
|
import DeleteIcon from '../widgets/icons/delete'
|
|
|
|
import DuplicateIcon from '../widgets/icons/duplicate'
|
2020-11-13 03:48:59 +01:00
|
|
|
import OptionsIcon from '../widgets/icons/options'
|
|
|
|
import Menu from '../widgets/menu'
|
|
|
|
import MenuWrapper from '../widgets/menuWrapper'
|
2020-10-26 12:43:16 +01:00
|
|
|
|
2020-10-25 09:47:50 +01:00
|
|
|
import './boardCard.scss'
|
2020-11-13 03:48:59 +01:00
|
|
|
import PropertyValueElement from './propertyValueElement'
|
2020-10-08 18:21:27 +02:00
|
|
|
|
|
|
|
type BoardCardProps = {
|
2020-10-20 21:50:53 +02:00
|
|
|
card: Card
|
|
|
|
visiblePropertyTemplates: IPropertyTemplate[]
|
2020-10-22 00:58:41 +02:00
|
|
|
isSelected: boolean
|
2020-10-28 18:46:36 +01:00
|
|
|
isDropZone?: boolean
|
2020-10-20 21:50:53 +02:00
|
|
|
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void
|
2020-11-12 21:33:05 +01:00
|
|
|
onDragStart: (e: React.DragEvent<HTMLDivElement>) => void
|
|
|
|
onDragEnd: (e: React.DragEvent<HTMLDivElement>) => void
|
|
|
|
onDrop: (e: React.DragEvent<HTMLDivElement>) => void
|
2020-10-25 09:47:50 +01:00
|
|
|
intl: IntlShape
|
2020-12-17 21:02:12 +01:00
|
|
|
readonly: boolean
|
2020-10-08 18:21:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type BoardCardState = {
|
2020-10-20 21:50:53 +02:00
|
|
|
isDragged?: boolean
|
2020-10-28 18:46:36 +01:00
|
|
|
isDragOver?: 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-22 23:10:38 +02:00
|
|
|
shouldComponentUpdate(): boolean {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
render(): JSX.Element {
|
2020-10-25 09:47:50 +01:00
|
|
|
const {card, intl} = this.props
|
2020-10-20 21:50:53 +02:00
|
|
|
const visiblePropertyTemplates = this.props.visiblePropertyTemplates || []
|
2020-10-28 18:46:36 +01:00
|
|
|
let className = this.props.isSelected ? 'BoardCard selected' : 'BoardCard'
|
|
|
|
if (this.props.isDropZone && this.state.isDragOver) {
|
|
|
|
className += ' dragover'
|
|
|
|
}
|
2020-10-22 00:58:41 +02:00
|
|
|
|
2020-10-22 23:10:38 +02:00
|
|
|
const element = (
|
|
|
|
<div
|
2020-10-22 00:58:41 +02:00
|
|
|
className={className}
|
2020-12-17 21:02:12 +01:00
|
|
|
draggable={!this.props.readonly}
|
2020-10-20 21:50:53 +02:00
|
|
|
style={{opacity: this.state.isDragged ? 0.5 : 1}}
|
|
|
|
onClick={this.props.onClick}
|
|
|
|
onDragStart={(e) => {
|
2020-10-22 23:10:38 +02:00
|
|
|
this.setState({isDragged: true})
|
|
|
|
this.props.onDragStart(e)
|
2020-10-20 21:50:53 +02:00
|
|
|
}}
|
|
|
|
onDragEnd={(e) => {
|
2020-10-22 23:10:38 +02:00
|
|
|
this.setState({isDragged: false})
|
|
|
|
this.props.onDragEnd(e)
|
2020-10-20 21:50:53 +02:00
|
|
|
}}
|
2020-10-28 18:46:36 +01:00
|
|
|
|
2020-11-12 23:17:13 +01:00
|
|
|
onDragOver={() => {
|
2020-11-09 19:02:54 +01:00
|
|
|
if (!this.state.isDragOver) {
|
|
|
|
this.setState({isDragOver: true})
|
|
|
|
}
|
2020-10-28 18:46:36 +01:00
|
|
|
}}
|
2020-11-12 23:17:13 +01:00
|
|
|
onDragEnter={() => {
|
2020-11-09 19:02:54 +01:00
|
|
|
if (!this.state.isDragOver) {
|
|
|
|
this.setState({isDragOver: true})
|
|
|
|
}
|
2020-10-28 18:46:36 +01:00
|
|
|
}}
|
2020-11-12 23:17:13 +01:00
|
|
|
onDragLeave={() => {
|
2020-10-28 18:46:36 +01:00
|
|
|
this.setState({isDragOver: false})
|
|
|
|
}}
|
|
|
|
onDrop={(e) => {
|
|
|
|
this.setState({isDragOver: false})
|
|
|
|
if (this.props.isDropZone) {
|
|
|
|
this.props.onDrop(e)
|
|
|
|
}
|
|
|
|
}}
|
2020-10-20 21:50:53 +02:00
|
|
|
>
|
2020-12-17 21:02:12 +01:00
|
|
|
{!this.props.readonly &&
|
|
|
|
<MenuWrapper
|
|
|
|
className='optionsMenu'
|
|
|
|
stopPropagationOnToggle={true}
|
|
|
|
>
|
|
|
|
<IconButton icon={<OptionsIcon/>}/>
|
|
|
|
<Menu position='left'>
|
|
|
|
<Menu.Text
|
|
|
|
icon={<DeleteIcon/>}
|
|
|
|
id='delete'
|
|
|
|
name={intl.formatMessage({id: 'BoardCard.delete', defaultMessage: 'Delete'})}
|
|
|
|
onClick={() => mutator.deleteBlock(card, 'delete card')}
|
|
|
|
/>
|
|
|
|
<Menu.Text
|
|
|
|
icon={<DuplicateIcon/>}
|
|
|
|
id='duplicate'
|
|
|
|
name={intl.formatMessage({id: 'BoardCard.duplicate', defaultMessage: 'Duplicate'})}
|
|
|
|
onClick={() => {
|
|
|
|
mutator.duplicateCard(card.id)
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Menu>
|
|
|
|
</MenuWrapper>
|
|
|
|
}
|
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 }
|
2020-10-25 09:47:50 +01:00
|
|
|
<div key='__title'>{card.title || intl.formatMessage({id: 'BoardCard.untitled', defaultMessage: 'Untitled'})}</div>
|
2020-10-20 21:50:53 +02:00
|
|
|
</div>
|
2020-10-26 12:43:16 +01:00
|
|
|
{visiblePropertyTemplates.map((template) => (
|
|
|
|
<PropertyValueElement
|
|
|
|
key={template.id}
|
|
|
|
readOnly={true}
|
|
|
|
card={card}
|
|
|
|
propertyTemplate={template}
|
|
|
|
emptyDisplayValue=''
|
|
|
|
/>
|
|
|
|
))}
|
2020-10-22 23:10:38 +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-25 09:47:50 +01:00
|
|
|
export default injectIntl(BoardCard)
|