diff options
Diffstat (limited to 'webui/src')
-rw-r--r-- | webui/src/App.js | 41 | ||||
-rw-r--r-- | webui/src/Bug.js | 28 | ||||
-rw-r--r-- | webui/src/BugPage.js | 29 | ||||
-rw-r--r-- | webui/src/BugSummary.js | 114 | ||||
-rw-r--r-- | webui/src/Comment.js | 27 | ||||
-rw-r--r-- | webui/src/ListPage.js | 47 | ||||
-rw-r--r-- | webui/src/index.js | 20 |
7 files changed, 174 insertions, 132 deletions
diff --git a/webui/src/App.js b/webui/src/App.js index 1d6382e5..ced02e43 100644 --- a/webui/src/App.js +++ b/webui/src/App.js @@ -1,40 +1,39 @@ -import React from "react"; -import { withRouter, Switch, Route } from "react-router"; -import { Link } from "react-router-dom"; -import { withStyles } from "@material-ui/core/styles"; +import AppBar from '@material-ui/core/AppBar' +import CssBaseline from '@material-ui/core/CssBaseline' +import { withStyles } from '@material-ui/core/styles' +import Toolbar from '@material-ui/core/Toolbar' +import Typography from '@material-ui/core/Typography' +import React from 'react' +import { Route, Switch, withRouter } from 'react-router' +import { Link } from 'react-router-dom' -import AppBar from "@material-ui/core/AppBar"; -import CssBaseline from "@material-ui/core/CssBaseline"; -import Toolbar from "@material-ui/core/Toolbar"; -import Typography from "@material-ui/core/Typography"; - -import BugPage from "./BugPage"; -import ListPage from "./ListPage"; +import BugPage from './BugPage' +import ListPage from './ListPage' const styles = theme => ({ appTitle: { - color: "white", - textDecoration: "none" + color: 'white', + textDecoration: 'none' } -}); +}) -const App = ({ location, classes }) => ( +const App = ({location, classes}) => ( <React.Fragment> - <CssBaseline /> + <CssBaseline/> <AppBar position="static" color="primary"> <Toolbar> <Link to="/" className={classes.appTitle}> <Typography variant="title" color="inherit"> - git-bug-webui(1) + git-bug webui </Typography> </Link> </Toolbar> </AppBar> <Switch> - <Route path="/" exact component={ListPage} /> - <Route path="/bug/:id" exact component={BugPage} /> + <Route path="/" exact component={ListPage}/> + <Route path="/bug/:id" exact component={BugPage}/> </Switch> </React.Fragment> -); +) -export default withStyles(styles)(withRouter(App)); +export default withStyles(styles)(withRouter(App)) diff --git a/webui/src/Bug.js b/webui/src/Bug.js index bca23e58..91463b51 100644 --- a/webui/src/Bug.js +++ b/webui/src/Bug.js @@ -1,27 +1,27 @@ -import React from "react"; -import gql from "graphql-tag"; -import { withStyles } from "@material-ui/core/styles"; +import { withStyles } from '@material-ui/core/styles' +import gql from 'graphql-tag' +import React from 'react' +import BugSummary from './BugSummary' -import Comment from "./Comment"; -import BugSummary from "./BugSummary"; +import Comment from './Comment' const styles = theme => ({ main: { maxWidth: 600, - margin: "auto", + margin: 'auto', marginTop: theme.spacing.unit * 4 } -}); +}) -const Bug = ({ bug, classes }) => ( +const Bug = ({bug, classes}) => ( <main className={classes.main}> - <BugSummary bug={bug} /> + <BugSummary bug={bug}/> - {bug.comments.edges.map(({ cursor, node }) => ( - <Comment key={cursor} comment={node} /> + {bug.comments.edges.map(({cursor, node}) => ( + <Comment key={cursor} comment={node}/> ))} </main> -); +) Bug.fragment = gql` fragment Bug on Bug { @@ -38,6 +38,6 @@ Bug.fragment = gql` ${BugSummary.fragment} ${Comment.fragment} -`; +` -export default withStyles(styles)(Bug); +export default withStyles(styles)(Bug) diff --git a/webui/src/BugPage.js b/webui/src/BugPage.js index 0f415841..a91030ab 100644 --- a/webui/src/BugPage.js +++ b/webui/src/BugPage.js @@ -1,10 +1,9 @@ -import React from "react"; -import { Query } from "react-apollo"; -import gql from "graphql-tag"; +import CircularProgress from '@material-ui/core/CircularProgress' +import gql from 'graphql-tag' +import React from 'react' +import { Query } from 'react-apollo' -import CircularProgress from "@material-ui/core/CircularProgress"; - -import Bug from "./Bug"; +import Bug from './Bug' const QUERY = gql` query GetBug($id: String!) { @@ -16,16 +15,16 @@ const QUERY = gql` } ${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.defaultRepository.bug} />; +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.defaultRepository.bug}/> }} </Query> -); +) -export default BugPage; +export default BugPage diff --git a/webui/src/BugSummary.js b/webui/src/BugSummary.js index 469ab9a8..5ffa8e05 100644 --- a/webui/src/BugSummary.js +++ b/webui/src/BugSummary.js @@ -1,53 +1,93 @@ -import React from "react"; -import { Link } from "react-router-dom"; -import gql from "graphql-tag"; -import { withStyles } from "@material-ui/core/styles"; +import { withStyles } from '@material-ui/core/styles' +import TableCell from '@material-ui/core/TableCell/TableCell' +import TableRow from '@material-ui/core/TableRow/TableRow' +import Tooltip from '@material-ui/core/Tooltip/Tooltip' +import Typography from '@material-ui/core/Typography' +import ErrorOutline from '@material-ui/icons/ErrorOutline' +import gql from 'graphql-tag' +import React from 'react' +import { Link } from 'react-router-dom' +import * as moment from 'moment' -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 Open = ({className}) => <Tooltip title="Open"> + <ErrorOutline nativeColor='#28a745' className={className}/> +</Tooltip> + +const Closed = ({className}) => <Tooltip title="Closed"> + <ErrorOutline nativeColor='#cb2431' className={className}/> +</Tooltip> + +const Status = ({status, className}) => { + switch(status) { + case 'OPEN': return <Open className={className}/> + case 'CLOSED': return <Closed className={className}/> + default: return 'unknown status ' + status + } +} const styles = theme => ({ - labelList: { - display: "flex", - flexWrap: "wrap", - marginTop: theme.spacing.unit + cell: { + display: 'flex', + alignItems: 'center' }, - label: { - marginRight: theme.spacing.unit + status: { + margin: 10 }, - summary: { - marginBottom: theme.spacing.unit * 2 - } -}); + title: { + display: 'inline-block', + textDecoration: 'none' + }, + labels: { + display: 'inline-block', + paddingLeft: theme.spacing.unit, + '&>span': { + padding: '0 4px', + margin: '0 1px', + backgroundColor: '#da9898', + borderRadius: '3px', + } + }, +}) -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}> - <Link to={"/bug/" + bug.id.slice(0, 8)}>#{bug.id.slice(0, 8)}</Link> •{" "} - {bug.status.toUpperCase()} - </Typography> - <div className={classes.labelList}> - {bug.labels.map(label => ( - <Chip key={label} label={label} className={classes.label} /> - ))} +const BugSummary = ({bug, classes}) => ( + <TableRow hover> + <TableCell className={classes.cell}> + <Status status={bug.status} className={classes.status}/> + <div> + <Link to={'bug/'+bug.humanId}> + <Typography variant={'title'} className={classes.title}> + {bug.title} + </Typography> + </Link> + <span className={classes.labels}> + {bug.labels.map(l => ( + <span key={l}>{l}</span>) + )} + </span> + <Typography color={'textSecondary'}> + {bug.humanId} opened + <Tooltip title={moment(bug.createdAt).format('MMMM D, YYYY, h:mm a')}> + <span> {moment(bug.createdAt).fromNow()} </span> + </Tooltip> + by {bug.author.name} + </Typography> </div> - </CardContent> - </Card> -); + </TableCell> + </TableRow> +) BugSummary.fragment = gql` fragment BugSummary on Bug { id + humanId title status + createdAt labels + author { + name + } } -`; +` -export default withStyles(styles)(BugSummary); +export default withStyles(styles)(BugSummary) diff --git a/webui/src/Comment.js b/webui/src/Comment.js index a4fd1b40..bc108083 100644 --- a/webui/src/Comment.js +++ b/webui/src/Comment.js @@ -1,20 +1,19 @@ -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"; +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 { withStyles } from '@material-ui/core/styles' +import Typography from '@material-ui/core/Typography' +import gql from 'graphql-tag' +import React from 'react' const styles = theme => ({ comment: { marginBottom: theme.spacing.unit } -}); +}) -const Comment = withStyles(styles)(({ comment, classes }) => ( +const Comment = withStyles(styles)(({comment, classes}) => ( <Card className={classes.comment}> <CardHeader avatar={ @@ -29,7 +28,7 @@ const Comment = withStyles(styles)(({ comment, classes }) => ( <Typography component="p">{comment.message}</Typography> </CardContent> </Card> -)); +)) Comment.fragment = gql` fragment Comment on Comment { @@ -39,6 +38,6 @@ Comment.fragment = gql` email } } -`; +` -export default withStyles(styles)(Comment); +export default withStyles(styles)(Comment) diff --git a/webui/src/ListPage.js b/webui/src/ListPage.js index ed56e553..76350ec5 100644 --- a/webui/src/ListPage.js +++ b/webui/src/ListPage.js @@ -1,11 +1,12 @@ -import React from "react"; -import { Query } from "react-apollo"; -import gql from "graphql-tag"; -import { withStyles } from "@material-ui/core/styles"; +import CircularProgress from '@material-ui/core/CircularProgress' +import { withStyles } from '@material-ui/core/styles' +import Table from '@material-ui/core/Table/Table' +import TableBody from '@material-ui/core/TableBody/TableBody' +import gql from 'graphql-tag' +import React from 'react' +import { Query } from 'react-apollo' -import CircularProgress from "@material-ui/core/CircularProgress"; - -import BugSummary from "./BugSummary"; +import BugSummary from './BugSummary' const QUERY = gql` { @@ -22,32 +23,36 @@ const QUERY = gql` } ${BugSummary.fragment} -`; +` const styles = theme => ({ main: { maxWidth: 600, - margin: "auto", + margin: 'auto', marginTop: theme.spacing.unit * 4 } -}); +}) -const List = withStyles(styles)(({ bugs, classes }) => ( +const List = withStyles(styles)(({bugs, classes}) => ( <main className={classes.main}> - {bugs.edges.map(({ cursor, node }) => ( - <BugSummary bug={node} key={cursor} /> - ))} + <Table className={classes.table}> + <TableBody> + {bugs.edges.map(({ cursor, node }) => ( + <BugSummary bug={node} key={cursor} /> + ))} + </TableBody> + </Table> </main> -)); +)) const ListPage = () => ( <Query query={QUERY}> - {({ loading, error, data }) => { - if (loading) return <CircularProgress />; - if (error) return <p>Error.</p>; - return <List bugs={data.defaultRepository.bugs} />; + {({loading, error, data}) => { + if (loading) return <CircularProgress/> + if (error) return <p>Error.</p> + return <List bugs={data.defaultRepository.bugs}/> }} </Query> -); +) -export default ListPage; +export default ListPage diff --git a/webui/src/index.js b/webui/src/index.js index 80b2651d..c34cc7cc 100644 --- a/webui/src/index.js +++ b/webui/src/index.js @@ -1,23 +1,23 @@ -import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter } from "react-router-dom"; -import ApolloClient from "apollo-boost"; -import { ApolloProvider } from "react-apollo"; +import ApolloClient from 'apollo-boost' +import React from 'react' +import { ApolloProvider } from 'react-apollo' +import ReactDOM from 'react-dom' +import { BrowserRouter } from 'react-router-dom' -import App from "./App"; +import App from './App' const client = new ApolloClient({ uri: "/graphql", connectToDevTools: true -}); +}) ReactDOM.render( <ApolloProvider client={client}> <BrowserRouter> <React.Fragment> - <App /> + <App/> </React.Fragment> </BrowserRouter> </ApolloProvider>, - document.getElementById("root") -); + document.getElementById('root') +) |