diff options
-rw-r--r-- | webui/src/App.js | 4 | ||||
-rw-r--r-- | webui/src/Bug.js | 101 | ||||
-rw-r--r-- | webui/src/BugPage.js | 29 | ||||
-rw-r--r-- | webui/src/BugSummary.js | 51 | ||||
-rw-r--r-- | webui/src/Comment.js | 44 |
5 files changed, 143 insertions, 86 deletions
diff --git a/webui/src/App.js b/webui/src/App.js index ddab0691..9cb3cdc7 100644 --- a/webui/src/App.js +++ b/webui/src/App.js @@ -6,7 +6,7 @@ import CssBaseline from "@material-ui/core/CssBaseline"; import Toolbar from "@material-ui/core/Toolbar"; import Typography from "@material-ui/core/Typography"; -import Bug from "./Bug"; +import BugPage from "./BugPage"; const Home = () => <h1>Home</h1>; @@ -22,7 +22,7 @@ const App = ({ location }) => ( </AppBar> <Switch> <Route path="/" exact component={Home} /> - <Route path="/bug/:id" exact component={Bug} /> + <Route path="/bug/:id" exact component={BugPage} /> </Switch> </React.Fragment> ); diff --git a/webui/src/Bug.js b/webui/src/Bug.js index de61bc8c..28558a13 100644 --- a/webui/src/Bug.js +++ b/webui/src/Bug.js @@ -1,105 +1,38 @@ import React from "react"; -import { Query } from "react-apollo"; import gql from "graphql-tag"; import { withStyles } from "@material-ui/core/styles"; -import Avatar from "@material-ui/core/Avatar"; -import Card from "@material-ui/core/Card"; -import CardContent from "@material-ui/core/CardContent"; -import CardHeader from "@material-ui/core/CardHeader"; -import Chip from "@material-ui/core/Chip"; -import CircularProgress from "@material-ui/core/CircularProgress"; -import Typography from "@material-ui/core/Typography"; +import Comment from "./Comment"; +import BugSummary from "./BugSummary"; const styles = theme => ({ main: { maxWidth: 600, margin: "auto", marginTop: theme.spacing.unit * 4 - }, - labelList: { - display: "flex", - flexWrap: "wrap", - marginTop: theme.spacing.unit - }, - label: { - marginRight: theme.spacing.unit - }, - summary: { - marginBottom: theme.spacing.unit * 2 - }, - comment: { - marginBottom: theme.spacing.unit } }); -const QUERY = gql` - query GetBug($id: BugID!) { - bug(id: $id) { - id - title - status - labels - comments { - message - author { - name - email - } - } - } - } -`; - -const Comment = withStyles(styles)(({ comment, classes }) => ( - <Card className={classes.comment}> - <CardHeader - avatar={ - <Avatar aria-label={comment.author.name}> - {comment.author.name[0].toUpperCase()} - </Avatar> - } - title={comment.author.name} - subheader={comment.author.email} - /> - <CardContent> - <Typography component="p">{comment.message}</Typography> - </CardContent> - </Card> -)); - -const BugView = withStyles(styles)(({ bug, classes }) => ( +const Bug = ({ bug, classes }) => ( <main className={classes.main}> - <Card className={classes.summary}> - <CardContent> - <Typography variant="headline" component="h2"> - {bug.title} - </Typography> - <Typography variant="subheading" component="h3" title={bug.id}> - #{bug.id.slice(0, 8)} • {bug.status.toUpperCase()} - </Typography> - <div className={classes.labelList}> - {bug.labels.map(label => ( - <Chip key={label} label={label} className={classes.label} /> - ))} - </div> - </CardContent> - </Card> + <BugSummary bug={bug} /> {bug.comments.map((comment, index) => ( <Comment key={index} comment={comment} /> ))} </main> -)); - -const Bug = ({ match }) => ( - <Query query={QUERY} variables={{ id: match.params.id }}> - {({ loading, error, data }) => { - if (loading) return <CircularProgress />; - if (error) return <p>Error.</p>; - return <BugView bug={data.bug} />; - }} - </Query> ); -export default Bug; +Bug.fragment = gql` + fragment Bug on Bug { + ...BugSummary + comments { + ...Comment + } + } + + ${BugSummary.fragment} + ${Comment.fragment} +`; + +export default withStyles(styles)(Bug); diff --git a/webui/src/BugPage.js b/webui/src/BugPage.js new file mode 100644 index 00000000..ec0872eb --- /dev/null +++ b/webui/src/BugPage.js @@ -0,0 +1,29 @@ +import React from "react"; +import { Query } from "react-apollo"; +import gql from "graphql-tag"; + +import CircularProgress from "@material-ui/core/CircularProgress"; + +import Bug from "./Bug"; + +const QUERY = gql` + query GetBug($id: BugID!) { + bug(id: $id) { + ...Bug + } + } + + ${Bug.fragment} +`; + +const BugPage = ({ match }) => ( + <Query query={QUERY} variables={{ id: match.params.id }}> + {({ loading, error, data }) => { + if (loading) return <CircularProgress />; + if (error) return <p>Error.</p>; + return <Bug bug={data.bug} />; + }} + </Query> +); + +export default BugPage; diff --git a/webui/src/BugSummary.js b/webui/src/BugSummary.js new file mode 100644 index 00000000..461fe2d0 --- /dev/null +++ b/webui/src/BugSummary.js @@ -0,0 +1,51 @@ +import React from "react"; +import gql from "graphql-tag"; +import { withStyles } from "@material-ui/core/styles"; + +import Card from "@material-ui/core/Card"; +import CardContent from "@material-ui/core/CardContent"; +import Chip from "@material-ui/core/Chip"; +import Typography from "@material-ui/core/Typography"; + +const styles = theme => ({ + labelList: { + display: "flex", + flexWrap: "wrap", + marginTop: theme.spacing.unit + }, + label: { + marginRight: theme.spacing.unit + }, + summary: { + marginBottom: theme.spacing.unit * 2 + } +}); + +const BugSummary = ({ bug, classes }) => ( + <Card className={classes.summary}> + <CardContent> + <Typography variant="headline" component="h2"> + {bug.title} + </Typography> + <Typography variant="subheading" component="h3" title={bug.id}> + #{bug.id.slice(0, 8)} • {bug.status.toUpperCase()} + </Typography> + <div className={classes.labelList}> + {bug.labels.map(label => ( + <Chip key={label} label={label} className={classes.label} /> + ))} + </div> + </CardContent> + </Card> +); + +BugSummary.fragment = gql` + fragment BugSummary on Bug { + id + title + status + labels + } +`; + +export default withStyles(styles)(BugSummary); diff --git a/webui/src/Comment.js b/webui/src/Comment.js new file mode 100644 index 00000000..a4fd1b40 --- /dev/null +++ b/webui/src/Comment.js @@ -0,0 +1,44 @@ +import React from "react"; +import gql from "graphql-tag"; +import { withStyles } from "@material-ui/core/styles"; + +import Avatar from "@material-ui/core/Avatar"; +import Card from "@material-ui/core/Card"; +import CardContent from "@material-ui/core/CardContent"; +import CardHeader from "@material-ui/core/CardHeader"; +import Typography from "@material-ui/core/Typography"; + +const styles = theme => ({ + comment: { + marginBottom: theme.spacing.unit + } +}); + +const Comment = withStyles(styles)(({ comment, classes }) => ( + <Card className={classes.comment}> + <CardHeader + avatar={ + <Avatar aria-label={comment.author.name}> + {comment.author.name[0].toUpperCase()} + </Avatar> + } + title={comment.author.name} + subheader={comment.author.email} + /> + <CardContent> + <Typography component="p">{comment.message}</Typography> + </CardContent> + </Card> +)); + +Comment.fragment = gql` + fragment Comment on Comment { + message + author { + name + email + } + } +`; + +export default withStyles(styles)(Comment); |