Newer
Older
piotr.kupczyk@id.ethz.ch
committed
import _ from 'lodash'
import React from 'react'
import { withStyles } from '@material-ui/core/styles'
import TableCell from '@material-ui/core/TableCell'
piotr.kupczyk@id.ethz.ch
committed
import Link from '@material-ui/core/Link'
import messages from '@src/js/common/messages.js'
piotr.kupczyk@id.ethz.ch
committed
import logger from '@src/js/common/logger.js'
piotr.kupczyk@id.ethz.ch
committed
const TRUNCATE_HEIGHT = 100
piotr.kupczyk@id.ethz.ch
committed
const TRUNCATE_WIDTH = 400
piotr.kupczyk@id.ethz.ch
committed
const MORE_HEIGHT = 20
piotr.kupczyk@id.ethz.ch
committed
piotr.kupczyk@id.ethz.ch
committed
const styles = theme => ({
cell: {
piotr.kupczyk@id.ethz.ch
committed
paddingTop: theme.spacing(1),
paddingBottom: theme.spacing(1),
paddingLeft: 0,
paddingRight: theme.spacing(2),
piotr.kupczyk@id.ethz.ch
committed
borderColor: theme.palette.border.secondary,
'&:empty:before': {
content: '"\\a0"'
}
piotr.kupczyk@id.ethz.ch
committed
},
nowrap: {
whiteSpace: 'nowrap'
piotr.kupczyk@id.ethz.ch
committed
},
truncate: {
maxHeight: TRUNCATE_HEIGHT + 'px',
piotr.kupczyk@id.ethz.ch
committed
maxWidth: TRUNCATE_WIDTH,
piotr.kupczyk@id.ethz.ch
committed
overflow: 'hidden'
piotr.kupczyk@id.ethz.ch
committed
},
truncateWithMore: {
maxHeight: TRUNCATE_HEIGHT - MORE_HEIGHT + 'px',
piotr.kupczyk@id.ethz.ch
committed
maxWidth: TRUNCATE_WIDTH,
piotr.kupczyk@id.ethz.ch
committed
overflow: 'hidden'
piotr.kupczyk@id.ethz.ch
committed
}
})
class GridCell extends React.PureComponent {
constructor(props) {
super(props)
piotr.kupczyk@id.ethz.ch
committed
this.state = {
piotr.kupczyk@id.ethz.ch
committed
more: false
piotr.kupczyk@id.ethz.ch
committed
}
piotr.kupczyk@id.ethz.ch
committed
this.ref = React.createRef()
piotr.kupczyk@id.ethz.ch
committed
this.handleMoreClick = this.handleMoreClick.bind(this)
piotr.kupczyk@id.ethz.ch
committed
}
componentDidMount() {
piotr.kupczyk@id.ethz.ch
committed
this.componentDidUpdate()
piotr.kupczyk@id.ethz.ch
committed
}
componentDidUpdate() {
this.renderDOMValue()
piotr.kupczyk@id.ethz.ch
committed
const { column, row, onMeasured } = this.props
if (column.truncate && this.ref.current) {
piotr.kupczyk@id.ethz.ch
committed
onMeasured(this.ref, column, row)
}
piotr.kupczyk@id.ethz.ch
committed
}
piotr.kupczyk@id.ethz.ch
committed
handleMoreClick() {
this.setState(state => ({
piotr.kupczyk@id.ethz.ch
committed
more: !state.more
piotr.kupczyk@id.ethz.ch
committed
}))
piotr.kupczyk@id.ethz.ch
committed
}
render() {
logger.log(logger.DEBUG, 'GridCell.render')
piotr.kupczyk@id.ethz.ch
committed
const { column, height, className, classes } = this.props
piotr.kupczyk@id.ethz.ch
committed
const { more } = this.state
const cellClasses = [classes.cell]
piotr.kupczyk@id.ethz.ch
committed
if (className) {
cellClasses.push(className)
}
piotr.kupczyk@id.ethz.ch
committed
piotr.kupczyk@id.ethz.ch
committed
const divClasses = []
if (column.nowrap) {
divClasses.push(classes.nowrap)
}
piotr.kupczyk@id.ethz.ch
committed
if (column.truncate && !more) {
piotr.kupczyk@id.ethz.ch
committed
if (height && height > TRUNCATE_HEIGHT) {
divClasses.push(classes.truncateWithMore)
} else {
divClasses.push(classes.truncate)
}
piotr.kupczyk@id.ethz.ch
committed
}
return (
piotr.kupczyk@id.ethz.ch
committed
<TableCell key={column.name} classes={{ root: cellClasses.join(' ') }}>
<div ref={this.ref} className={divClasses.join(' ')}>
{column.renderDOMValue ? null : this.renderValue()}
</div>
{this.renderMore()}
</TableCell>
)
piotr.kupczyk@id.ethz.ch
committed
}
renderValue() {
piotr.kupczyk@id.ethz.ch
committed
const { row, column } = this.props
piotr.kupczyk@id.ethz.ch
committed
piotr.kupczyk@id.ethz.ch
committed
const value = column.getValue({ row, column, operation: 'render' })
piotr.kupczyk@id.ethz.ch
committed
const renderedValue = column.renderValue
? column.renderValue({
value,
row,
piotr.kupczyk@id.ethz.ch
committed
column
piotr.kupczyk@id.ethz.ch
committed
})
: value
if (renderedValue === null || renderedValue === undefined) {
piotr.kupczyk@id.ethz.ch
committed
return null
piotr.kupczyk@id.ethz.ch
committed
} else if (_.isNumber(renderedValue) || _.isBoolean(renderedValue)) {
return String(renderedValue)
} else {
return renderedValue
}
}
piotr.kupczyk@id.ethz.ch
committed
renderDOMValue() {
piotr.kupczyk@id.ethz.ch
committed
const { row, column } = this.props
piotr.kupczyk@id.ethz.ch
committed
if (column.renderDOMValue && this.ref.current) {
piotr.kupczyk@id.ethz.ch
committed
const value = column.getValue({ row, column, operation: 'render' })
piotr.kupczyk@id.ethz.ch
committed
column.renderDOMValue({
container: this.ref.current,
value,
row,
piotr.kupczyk@id.ethz.ch
committed
column
piotr.kupczyk@id.ethz.ch
committed
})
}
}
piotr.kupczyk@id.ethz.ch
committed
renderMore() {
piotr.kupczyk@id.ethz.ch
committed
const { column, height } = this.props
const { more } = this.state
piotr.kupczyk@id.ethz.ch
committed
piotr.kupczyk@id.ethz.ch
committed
if (column.truncate && height && height > TRUNCATE_HEIGHT) {
piotr.kupczyk@id.ethz.ch
committed
return (
<div>
<Link onClick={this.handleMoreClick}>
{more ? messages.get(messages.LESS) : messages.get(messages.MORE)}
</Link>
</div>
)
} else {
return null
piotr.kupczyk@id.ethz.ch
committed
}
}
piotr.kupczyk@id.ethz.ch
committed
}
export default withStyles(styles)(GridCell)