Files
Superalgos/client/components/DescendentsTree.js
T

259 lines
6.5 KiB
JavaScript

import React, { Component } from 'react'
import {graphql, compose} from 'react-apollo'
import {getDescendentsQuery} from '../queries/queries'
// Materia UI
import { withStyles } from '@material-ui/core/styles'
import Card from '@material-ui/core/Card'
import CardActionArea from '@material-ui/core/CardActionArea'
import CardActions from '@material-ui/core/CardActions'
import CardContent from '@material-ui/core/CardContent'
import CardMedia from '@material-ui/core/CardMedia'
import Typography from '@material-ui/core/Typography'
import Grid from '@material-ui/core/Grid'
// Material UI Nestled Lists
import ListSubheader from '@material-ui/core/ListSubheader';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Collapse from '@material-ui/core/Collapse';
import ExpandLess from '@material-ui/icons/ExpandLess';
import ExpandMore from '@material-ui/icons/ExpandMore';
import StarBorder from '@material-ui/icons/StarBorder';
// Images
import PortraitImage from '../img/portrait.jpg'
const styles = theme => ({
card: {
maxWidth: 300,
minWidth: 300,
paddingTop: '30'
},
media: {
height: 0,
paddingTop: '56.25%', // 16:9,
marginTop: '30',
minWidth: 300
},
typography: {
maxWidth: 345,
minWidth: 300,
paddingTop: '30'
},
appBar: {
position: 'relative'
},
flex: {
flex: 1
},
grid: {
paddingTop: '30',
marginTop: 30
},
list: {
width: '80%',
marginLeft: '10%',
marginTop: 25
},
button: {
margin: theme.spacing.unit,
marginTop: theme.spacing.unit * 3
},
nested: {
paddingLeft: theme.spacing.unit * 4,
},
})
class DescendentsTree extends Component {
constructor (props) {
super(props)
this.state = {
id: '',
open: true
}
}
handleClick = () => {
this.setState(state => ({ open: !state.open }));
};
displayIcons(amount) {
switch (amount) {
case 1: return (
<div>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
</div>
)
case 2: return (
<div>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
</div>
)
case 3: return (
<div>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
</div>
)
default: return(<div/>)
}
}
displayNestedListItems(node, level) {
const { classes } = this.props
return node.descendents.map(descendent => {
return (
<div key={descendent.alias}>
<ListItem button className={classes.nested}>
{this.displayIcons(level)}
<Card className={classes.card}>
<CardActionArea>
<CardMedia
className={classes.media}
image={PortraitImage}
title='User Profile'
/>
<CardContent>
<Typography gutterBottom variant='headline' component='h2'>
{descendent.alias}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Grid container justify='center' spacing={8}>
<Grid item />
</Grid>
</CardActions>
</Card>
</ListItem>
{this.displayNestedList(descendent, level)}
</div>
)
}
)
}
displayNestedList(descendent, level) {
const primaryText = "Children of " + descendent.alias
if (descendent.descendents !== undefined) {
if (descendent.descendents.length > 0) {
return(
<List component="div" disablePadding>
<ListItem button onClick={ () => {
this.setState(state => ({ [descendent.alias]: !state[descendent.alias] }));
}
}>
<ListItemText inset primary={primaryText} />
{this.state[descendent.alias] ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={this.state[descendent.alias]} timeout="auto" unmountOnExit>
{this.displayNestedListItems(descendent, level + 1)}
</Collapse>
</List>
)
} else {
return (<div/>)
}
}
}
displayTopList () {
let data = this.props.data
const { classes } = this.props
if (data.loading) {
return (<div> Loading Descendents... </div>)
} else {
if (data.users_Descendents === undefined) {
return (<div> No Descendents to Display </div>)
} else {
return data.users_Descendents.map(descendent => {
return (
<div key={descendent.alias}>
<ListItem button>
{this.displayIcons(1)}
<Card className={classes.card}>
<CardActionArea>
<CardMedia
className={classes.media}
image={PortraitImage}
title='User Profile'
/>
<CardContent>
<Typography gutterBottom variant='headline' component='h2'>
{descendent.alias}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Grid container justify='center' spacing={8}>
<Grid item />
</Grid>
</CardActions>
</Card>
</ListItem>
{this.displayNestedList(descendent, 1)}
</div>
)
})
}
}
}
render () {
const { classes } = this.props
return (
<div>
<List
component="nav"
subheader={<ListSubheader component="div"></ListSubheader>}
className={classes.list}
>
{this.displayTopList()}
</List>
</div>
)
}
}
export default compose(
graphql(getDescendentsQuery, { // What follows is the way to pass a parameter to a query.
options: (props) => {
return {
variables: {
name: 'getDescendentsQuery',
id: props.userId
}
}
}}),
withStyles(styles)
)(DescendentsTree) // This technique binds more than one query to a single component.