Newer
Older
piotr.kupczyk@id.ethz.ch
committed
import _ from 'lodash'
import React from 'react'
piotr.kupczyk@id.ethz.ch
committed
import autoBind from 'auto-bind'
piotr.kupczyk@id.ethz.ch
committed
import { withStyles } from '@material-ui/core/styles'
import { DragDropContext, Droppable } from 'react-beautiful-dnd'
piotr.kupczyk@id.ethz.ch
committed
import Popover from '@material-ui/core/Popover'
piotr.kupczyk@id.ethz.ch
committed
import Mask from '@src/js/components/common/loading/Mask.jsx'
piotr.kupczyk@id.ethz.ch
committed
import Container from '@src/js/components/common/form/Container.jsx'
piotr.kupczyk@id.ethz.ch
committed
import Button from '@src/js/components/common/form/Button.jsx'
import GridColumnsConfigRow from '@src/js/components/common/grid/GridColumnsConfigRow.jsx'
piotr.kupczyk@id.ethz.ch
committed
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 styles = theme => ({
piotr.kupczyk@id.ethz.ch
committed
container: {
piotr.kupczyk@id.ethz.ch
committed
display: 'flex',
piotr.kupczyk@id.ethz.ch
committed
alignItems: 'center',
paddingRight: theme.spacing(1)
piotr.kupczyk@id.ethz.ch
committed
},
piotr.kupczyk@id.ethz.ch
committed
columns: {
piotr.kupczyk@id.ethz.ch
committed
listStyle: 'none',
piotr.kupczyk@id.ethz.ch
committed
margin: 0,
padding: 0
piotr.kupczyk@id.ethz.ch
committed
},
buttons: {
piotr.kupczyk@id.ethz.ch
committed
display: 'flex',
whiteSpace: 'nowrap',
piotr.kupczyk@id.ethz.ch
committed
marginBottom: theme.spacing(1),
'& button': {
marginRight: theme.spacing(1)
}
piotr.kupczyk@id.ethz.ch
committed
}
})
piotr.kupczyk@id.ethz.ch
committed
class GridColumnsConfig extends React.PureComponent {
piotr.kupczyk@id.ethz.ch
committed
constructor(props) {
piotr.kupczyk@id.ethz.ch
committed
super(props)
piotr.kupczyk@id.ethz.ch
committed
autoBind(this)
piotr.kupczyk@id.ethz.ch
committed
this.state = {
el: null
}
}
piotr.kupczyk@id.ethz.ch
committed
handleOpen(event) {
piotr.kupczyk@id.ethz.ch
committed
this.setState({
el: event.currentTarget
})
}
piotr.kupczyk@id.ethz.ch
committed
handleClose() {
piotr.kupczyk@id.ethz.ch
committed
this.setState({
el: null
})
}
handleDragEnd(result) {
if (!result.destination) {
return
}
this.props.onOrderChange(result.source.index, result.destination.index)
}
piotr.kupczyk@id.ethz.ch
committed
handleShowAll() {
this.handleVisibleChangeAll(true)
}
handleHideAll() {
this.handleVisibleChangeAll(false)
}
handleVisibleChangeAll(visibility) {
const { columns, onVisibleChange } = this.props
const visibilityMap = columns.reduce((map, column) => {
map[column.name] = visibility
return map
}, {})
onVisibleChange(visibilityMap)
}
piotr.kupczyk@id.ethz.ch
committed
render() {
piotr.kupczyk@id.ethz.ch
committed
logger.log(logger.DEBUG, 'GridColumnsConfig.render')
piotr.kupczyk@id.ethz.ch
committed
piotr.kupczyk@id.ethz.ch
committed
const { id, classes, loading } = this.props
piotr.kupczyk@id.ethz.ch
committed
const { el } = this.state
return (
piotr.kupczyk@id.ethz.ch
committed
<div className={classes.container}>
piotr.kupczyk@id.ethz.ch
committed
<Button
piotr.kupczyk@id.ethz.ch
committed
id={id + '.columns-button-id'}
piotr.kupczyk@id.ethz.ch
committed
label={messages.get(messages.COLUMNS)}
piotr.kupczyk@id.ethz.ch
committed
color='default'
variant='outlined'
onClick={this.handleOpen}
piotr.kupczyk@id.ethz.ch
committed
/>
piotr.kupczyk@id.ethz.ch
committed
<Popover
piotr.kupczyk@id.ethz.ch
committed
id={id + '.columns-popup-id'}
piotr.kupczyk@id.ethz.ch
committed
open={Boolean(el)}
anchorEl={el}
onClose={this.handleClose}
anchorOrigin={{
piotr.kupczyk@id.ethz.ch
committed
vertical: 'bottom',
piotr.kupczyk@id.ethz.ch
committed
horizontal: 'left'
piotr.kupczyk@id.ethz.ch
committed
}}
transformOrigin={{
piotr.kupczyk@id.ethz.ch
committed
vertical: 'top',
piotr.kupczyk@id.ethz.ch
committed
horizontal: 'left'
piotr.kupczyk@id.ethz.ch
committed
}}
>
piotr.kupczyk@id.ethz.ch
committed
<Mask visible={loading}>
piotr.kupczyk@id.ethz.ch
committed
<Container square={true}>{this.renderColumns()}</Container>
piotr.kupczyk@id.ethz.ch
committed
</Mask>
piotr.kupczyk@id.ethz.ch
committed
</Popover>
piotr.kupczyk@id.ethz.ch
committed
</div>
piotr.kupczyk@id.ethz.ch
committed
)
}
piotr.kupczyk@id.ethz.ch
committed
renderColumns() {
const { classes, columns, columnsVisibility, onVisibleChange } = this.props
return (
<div>
piotr.kupczyk@id.ethz.ch
committed
<div className={classes.buttons}>
<Button
label={messages.get(messages.SHOW_ALL)}
onClick={this.handleShowAll}
/>
<Button
label={messages.get(messages.HIDE_ALL)}
onClick={this.handleHideAll}
/>
</div>
piotr.kupczyk@id.ethz.ch
committed
<DragDropContext onDragEnd={this.handleDragEnd}>
<Droppable droppableId='root'>
{provided => (
<ol
ref={provided.innerRef}
{...provided.droppableProps}
piotr.kupczyk@id.ethz.ch
committed
className={classes.columns}
piotr.kupczyk@id.ethz.ch
committed
>
{columns.map((column, index) => (
piotr.kupczyk@id.ethz.ch
committed
<GridColumnsConfigRow
piotr.kupczyk@id.ethz.ch
committed
key={column.name}
column={column}
visible={columnsVisibility[column.name]}
index={index}
onVisibleChange={onVisibleChange}
/>
))}
{provided.placeholder}
</ol>
)}
</Droppable>
</DragDropContext>
</div>
)
}
piotr.kupczyk@id.ethz.ch
committed
}
piotr.kupczyk@id.ethz.ch
committed
export default _.flow(withStyles(styles))(GridColumnsConfig)