aboutsummaryrefslogtreecommitdiffstats
path: root/webui
diff options
context:
space:
mode:
Diffstat (limited to 'webui')
-rw-r--r--webui/src/App.js4
-rw-r--r--webui/src/Bug.js101
-rw-r--r--webui/src/BugPage.js29
-rw-r--r--webui/src/BugSummary.js51
-rw-r--r--webui/src/Comment.js44
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);