From 1984d4343db770fc2c8e251a81f1ab997a4c4d5e Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Wed, 15 Aug 2018 20:31:53 +0200 Subject: webui: rework of the bug page with a timeline --- webui/src/bug/Bug.js | 78 ++++++++++++++++++++++++++++++++++-------- webui/src/bug/BugPage.js | 30 ---------------- webui/src/bug/BugQuery.js | 30 ++++++++++++++++ webui/src/bug/Comment.js | 43 ----------------------- webui/src/bug/Message.js | 75 ++++++++++++++++++++++++++++++++++++++++ webui/src/bug/Timeline.js | 43 +++++++++++++++++++++++ webui/src/bug/TimelineQuery.js | 39 +++++++++++++++++++++ 7 files changed, 251 insertions(+), 87 deletions(-) delete mode 100644 webui/src/bug/BugPage.js create mode 100644 webui/src/bug/BugQuery.js delete mode 100644 webui/src/bug/Comment.js create mode 100644 webui/src/bug/Message.js create mode 100644 webui/src/bug/Timeline.js create mode 100644 webui/src/bug/TimelineQuery.js (limited to 'webui/src/bug') diff --git a/webui/src/bug/Bug.js b/webui/src/bug/Bug.js index 33ecdd79..3847c755 100644 --- a/webui/src/bug/Bug.js +++ b/webui/src/bug/Bug.js @@ -1,39 +1,89 @@ import { withStyles } from '@material-ui/core/styles' +import Tooltip from '@material-ui/core/Tooltip/Tooltip' +import Typography from '@material-ui/core/Typography/Typography' import gql from 'graphql-tag' +import * as moment from 'moment' import React from 'react' - -import Comment from './Comment' +import TimelineQuery from './TimelineQuery' const styles = theme => ({ main: { maxWidth: 600, margin: 'auto', marginTop: theme.spacing.unit * 4 + }, + header: {}, + title: { + ...theme.typography.headline + }, + id: { + ...theme.typography.subheading, + marginLeft: 15, + }, + container: { + display: 'flex' + }, + timeline: { + width: '70%', + marginTop: 20, + marginRight: 20, + }, + sidebar: { + width: '30%' + }, + label: { + backgroundColor: '#da9898', + borderRadius: '3px', + paddingLeft: '10px', + margin: '2px 20px auto 2px', + fontWeight: 'bold', } }) const Bug = ({bug, classes}) => (
+
+ {bug.title} + {bug.humanId} + + + {bug.author.name} + opened this bug + + {moment(bug.createdAt).fromNow()} + + +
- {bug.comments.edges.map(({cursor, node}) => ( - - ))} +
+
+ +
+
+ Labels + {bug.labels.map(l => ( + + {l} + + ))} +
+
) Bug.fragment = gql` fragment Bug on Bug { - comments(first: 10) { - edges { - cursor - node { - ...Comment - } - } + id + humanId + status + title + labels + createdAt + author { + email + name } } - - ${Comment.fragment} ` export default withStyles(styles)(Bug) diff --git a/webui/src/bug/BugPage.js b/webui/src/bug/BugPage.js deleted file mode 100644 index a91030ab..00000000 --- a/webui/src/bug/BugPage.js +++ /dev/null @@ -1,30 +0,0 @@ -import CircularProgress from '@material-ui/core/CircularProgress' -import gql from 'graphql-tag' -import React from 'react' -import { Query } from 'react-apollo' - -import Bug from './Bug' - -const QUERY = gql` - query GetBug($id: String!) { - defaultRepository { - bug(prefix: $id) { - ...Bug - } - } - } - - ${Bug.fragment} -` - -const BugPage = ({match}) => ( - - {({loading, error, data}) => { - if (loading) return - if (error) return

Error.

- return - }} -
-) - -export default BugPage diff --git a/webui/src/bug/BugQuery.js b/webui/src/bug/BugQuery.js new file mode 100644 index 00000000..22421414 --- /dev/null +++ b/webui/src/bug/BugQuery.js @@ -0,0 +1,30 @@ +import CircularProgress from '@material-ui/core/CircularProgress' +import gql from 'graphql-tag' +import React from 'react' +import { Query } from 'react-apollo' + +import Bug from './Bug' + +const QUERY = gql` + query GetBug($id: String!) { + defaultRepository { + bug(prefix: $id) { + ...Bug + } + } + } + + ${Bug.fragment} +` + +const BugQuery = ({match}) => ( + + {({loading, error, data}) => { + if (loading) return + if (error) return

Error: {error}

+ return + }} +
+) + +export default BugQuery diff --git a/webui/src/bug/Comment.js b/webui/src/bug/Comment.js deleted file mode 100644 index bc108083..00000000 --- a/webui/src/bug/Comment.js +++ /dev/null @@ -1,43 +0,0 @@ -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}) => ( - - - {comment.author.name[0].toUpperCase()} - - } - title={comment.author.name} - subheader={comment.author.email} - /> - - {comment.message} - - -)) - -Comment.fragment = gql` - fragment Comment on Comment { - message - author { - name - email - } - } -` - -export default withStyles(styles)(Comment) diff --git a/webui/src/bug/Message.js b/webui/src/bug/Message.js new file mode 100644 index 00000000..04c7dfab --- /dev/null +++ b/webui/src/bug/Message.js @@ -0,0 +1,75 @@ +import { withStyles } from '@material-ui/core/styles' +import Tooltip from '@material-ui/core/Tooltip/Tooltip' +import Typography from '@material-ui/core/Typography' +import gql from 'graphql-tag' +import * as moment from 'moment' +import React from 'react' + +const styles = theme => ({ + header: { + ...theme.typography.body2, + padding: '3px 3px 3px 6px', + backgroundColor: '#f1f8ff', + border: '1px solid #d1d5da', + borderTopLeftRadius: 3, + borderTopRightRadius: 3, + }, + author: { + ...theme.typography.body2, + fontWeight: 'bold' + }, + message: { + borderLeft: '1px solid #d1d5da', + borderRight: '1px solid #d1d5da', + borderBottom: '1px solid #d1d5da', + borderBottomLeftRadius: 3, + borderBottomRightRadius: 3, + backgroundColor: '#fff', + minHeight: 50 + } +}) + +const Message = ({message, classes}) => ( +
+
+ + {message.author.name} + + commented + + {moment(message.date).fromNow()} + +
+
+ {message.message} +
+
+) + +Message.createFragment = gql` + fragment Create on Operation { + ... on CreateOperation { + date + author { + name + email + } + message + } + } +` + +Message.commentFragment = gql` + fragment Comment on Operation { + ... on AddCommentOperation { + date + author { + name + email + } + message + } + } +` + +export default withStyles(styles)(Message) diff --git a/webui/src/bug/Timeline.js b/webui/src/bug/Timeline.js new file mode 100644 index 00000000..0c4100ec --- /dev/null +++ b/webui/src/bug/Timeline.js @@ -0,0 +1,43 @@ +import { withStyles } from '@material-ui/core/styles' +import React from 'react' +import Message from './Message' + +const styles = theme => ({ + main: { + '& > *:not(:last-child)': { + marginBottom: 10 + } + } +}) + +class Timeline extends React.Component { + + props: { + ops: Array, + fetchMore: (any) => any, + classes: any, + } + + render() { + const {ops, classes} = this.props + + return ( +
+ { ops.map((op, index) => { + switch (op.__typename) { + case 'CreateOperation': + return + case 'AddCommentOperation': + return + + default: + console.log('unsupported operation type ' + op.__typename) + return null + } + })} +
+ ) + } +} + +export default withStyles(styles)(Timeline) diff --git a/webui/src/bug/TimelineQuery.js b/webui/src/bug/TimelineQuery.js new file mode 100644 index 00000000..e773aac0 --- /dev/null +++ b/webui/src/bug/TimelineQuery.js @@ -0,0 +1,39 @@ +import CircularProgress from '@material-ui/core/CircularProgress' +import gql from 'graphql-tag' +import React from 'react' +import { Query } from 'react-apollo' +import Timeline from './Timeline' +import Message from './Message' + +const QUERY = gql` + query($id: String!, $first: Int = 10, $after: String) { + defaultRepository { + bug(prefix: $id) { + operations(first: $first, after: $after) { + nodes { + ...Create + ...Comment + } + pageInfo { + hasNextPage + endCursor + } + } + } + } + } + ${Message.createFragment} + ${Message.commentFragment} +` + +const TimelineQuery = ({id}) => ( + + {({loading, error, data, fetchMore}) => { + if (loading) return + if (error) return

Error: {error}

+ return + }} +
+) + +export default TimelineQuery -- cgit