webui: Rework timeline style

Quentin Gliech created

Change summary

webui/src/Author.js          | 29 ++++++-------
webui/src/bug/Bug.js         | 24 ++++++----
webui/src/bug/LabelChange.js |  6 ++
webui/src/bug/Message.js     | 77 +++++++++++++++++++++++++------------
webui/src/bug/SetStatus.js   |  1 
webui/src/bug/SetTitle.js    |  3 
webui/src/bug/Timeline.js    |  2 
7 files changed, 88 insertions(+), 54 deletions(-)

Detailed changes

webui/src/Author.js 🔗

@@ -1,28 +1,25 @@
-import { withStyles } from '@material-ui/core/styles';
 import Tooltip from '@material-ui/core/Tooltip/Tooltip';
+import MAvatar from '@material-ui/core/Avatar';
 import React from 'react';
 
-const styles = theme => ({
-  author: {
-    ...theme.typography.body2,
-  },
-  bold: {
-    fontWeight: 'bold',
-  },
-});
-
-const Author = ({ author, bold, classes }) => {
-  const klass = bold ? [classes.author, classes.bold] : [classes.author];
-
+const Author = ({ author, ...props }) => {
   if (!author.email) {
-    return <span className={klass.join(' ')}>{author.displayName}</span>;
+    return <span {...props}>{author.displayName}</span>;
   }
 
   return (
     <Tooltip title={author.email}>
-      <span className={klass.join(' ')}>{author.displayName}</span>
+      <span {...props}>{author.displayName}</span>
     </Tooltip>
   );
 };
 
-export default withStyles(styles)(Author);
+export const Avatar = ({ author, ...props }) => {
+  if (author.avatarUrl) {
+    return <MAvatar src={author.avatarUrl} {...props} />;
+  }
+
+  return <MAvatar {...props}>{author.displayName[0]}</MAvatar>;
+};
+
+export default Author;

webui/src/bug/Bug.js 🔗

@@ -9,29 +9,32 @@ import Label from '../Label';
 
 const styles = theme => ({
   main: {
-    maxWidth: 600,
+    maxWidth: 800,
     margin: 'auto',
     marginTop: theme.spacing.unit * 4,
   },
-  header: {},
+  header: {
+    marginLeft: theme.spacing.unit + 40,
+  },
   title: {
     ...theme.typography.headline,
   },
   id: {
     ...theme.typography.subheading,
-    marginLeft: 15,
+    marginLeft: theme.spacing.unit,
   },
   container: {
     display: 'flex',
-    marginBottom: 30,
+    marginBottom: theme.spacing.unit,
   },
   timeline: {
-    width: '70%',
-    marginTop: 20,
-    marginRight: 20,
+    flex: 1,
+    marginTop: theme.spacing.unit * 2,
+    marginRight: theme.spacing.unit * 2,
   },
   sidebar: {
-    width: '30%',
+    marginTop: theme.spacing.unit * 2,
+    flex: '0 0 200px',
   },
   labelList: {
     listStyle: 'none',
@@ -39,7 +42,8 @@ const styles = theme => ({
     margin: 0,
   },
   label: {
-    margin: '4px 0',
+    marginTop: theme.spacing.unit,
+    marginBottom: theme.spacing.unit,
     '& > *': {
       display: 'block',
     },
@@ -54,7 +58,7 @@ const Bug = ({ bug, classes }) => (
 
       <Typography color={'textSecondary'}>
         <Author author={bug.author} />
-        <span> opened this bug </span>
+        {' opened this bug '}
         <Date date={bug.createdAt} />
       </Typography>
     </div>

webui/src/bug/LabelChange.js 🔗

@@ -8,6 +8,10 @@ import Label from '../Label';
 const styles = theme => ({
   main: {
     ...theme.typography.body2,
+    marginLeft: theme.spacing.unit + 40,
+  },
+  author: {
+    fontWeight: 'bold',
   },
 });
 
@@ -15,7 +19,7 @@ const LabelChange = ({ op, classes }) => {
   const { added, removed } = op;
   return (
     <div className={classes.main}>
-      <Author author={op.author} bold />
+      <Author author={op.author} className={classes.author} />
       {added.length > 0 && <span> added the </span>}
       {added.map((label, index) => (
         <Label key={index} label={label} />

webui/src/bug/Message.js 🔗

@@ -1,43 +1,66 @@
 import { withStyles } from '@material-ui/core/styles';
-import Typography from '@material-ui/core/Typography';
+import Paper from '@material-ui/core/Paper';
 import gql from 'graphql-tag';
 import React from 'react';
 import Author from '../Author';
+import { Avatar } from '../Author';
 import Date from '../Date';
 
 const styles = theme => ({
+  author: {
+    fontWeight: 'bold',
+  },
+  container: {
+    display: 'flex',
+  },
+  avatar: {
+    marginTop: 2,
+  },
+  bubble: {
+    flex: 1,
+    marginLeft: theme.spacing.unit,
+  },
   header: {
     ...theme.typography.body2,
-    padding: '3px 3px 3px 6px',
-    backgroundColor: '#f1f8ff',
-    border: '1px solid #d1d5da',
-    borderTopLeftRadius: 3,
-    borderTopRightRadius: 3,
+    color: '#444',
+    padding: '0.5rem 1rem',
+    borderBottom: '1px solid #ddd',
+    display: 'flex',
+  },
+  title: {
+    flex: 1,
+  },
+  tag: {
+    ...theme.typography.button,
+    color: '#888',
+    border: '#ddd solid 1px',
+    padding: '0 0.5rem',
+    fontSize: '0.75rem',
+    borderRadius: 2,
+    marginLeft: '0.5rem',
   },
-  message: {
-    borderLeft: '1px solid #d1d5da',
-    borderRight: '1px solid #d1d5da',
-    borderBottom: '1px solid #d1d5da',
-    borderBottomLeftRadius: 3,
-    borderBottomRightRadius: 3,
-    backgroundColor: '#fff',
-    minHeight: 50,
-    padding: 5,
+  body: {
+    ...theme.typography.body1,
+    padding: '1rem',
     whiteSpace: 'pre-wrap',
   },
 });
 
 const Message = ({ op, classes }) => (
-  <div>
-    <div className={classes.header}>
-      <Author className={classes.author} author={op.author} bold />
-      <span> commented </span>
-      <Date date={op.createdAt} />
-    </div>
-    <div className={classes.message}>
-      <Typography>{op.message}</Typography>
-    </div>
-  </div>
+  <article className={classes.container}>
+    <Avatar author={op.author} className={classes.avatar} />
+    <Paper elevation={1} className={classes.bubble}>
+      <header className={classes.header}>
+        <div className={classes.title}>
+          <Author className={classes.author} author={op.author} />
+          <span> commented </span>
+          <Date date={op.createdAt} />
+        </div>
+        {op.edited && <div className={classes.tag}>Edited</div>}
+      </header>
+      <section className={classes.body}>{op.message}</section>
+    </Paper>
+  </article>
 );
 
 Message.createFragment = gql`
@@ -48,7 +71,9 @@ Message.createFragment = gql`
         name
         email
         displayName
+        avatarUrl
       }
+      edited
       message
     }
   }
@@ -62,7 +87,9 @@ Message.commentFragment = gql`
         name
         email
         displayName
+        avatarUrl
       }
+      edited
       message
     }
   }

webui/src/bug/SetStatus.js 🔗

@@ -7,6 +7,7 @@ import Date from '../Date';
 const styles = theme => ({
   main: {
     ...theme.typography.body2,
+    marginLeft: theme.spacing.unit + 40,
   },
 });
 

webui/src/bug/SetTitle.js 🔗

@@ -7,6 +7,7 @@ import Date from '../Date';
 const styles = theme => ({
   main: {
     ...theme.typography.body2,
+    marginLeft: theme.spacing.unit + 40,
   },
   bold: {
     fontWeight: 'bold',
@@ -16,7 +17,7 @@ const styles = theme => ({
 const SetTitle = ({ op, classes }) => {
   return (
     <div className={classes.main}>
-      <Author author={op.author} bold />
+      <Author author={op.author} className={classes.bold} />
       <span> changed the title from </span>
       <span className={classes.bold}>{op.was}</span>
       <span> to </span>

webui/src/bug/Timeline.js 🔗

@@ -8,7 +8,7 @@ import SetTitle from './SetTitle';
 const styles = theme => ({
   main: {
     '& > *:not(:last-child)': {
-      marginBottom: 10,
+      marginBottom: theme.spacing.unit * 2,
     },
   },
 });