diff options
Diffstat (limited to 'webui/src/pages')
-rw-r--r-- | webui/src/pages/bug/LabelChange.tsx | 8 | ||||
-rw-r--r-- | webui/src/pages/bug/Message.tsx | 1 | ||||
-rw-r--r-- | webui/src/pages/bug/SetStatus.tsx | 8 | ||||
-rw-r--r-- | webui/src/pages/bug/SetTitle.tsx | 8 | ||||
-rw-r--r-- | webui/src/pages/identity/BugList.tsx | 4 | ||||
-rw-r--r-- | webui/src/pages/identity/GetUserStatistic.graphql | 13 | ||||
-rw-r--r-- | webui/src/pages/identity/Identity.tsx | 207 | ||||
-rw-r--r-- | webui/src/pages/identity/IdentityQuery.tsx | 24 | ||||
-rw-r--r-- | webui/src/pages/identity/index.tsx | 1 | ||||
-rw-r--r-- | webui/src/pages/list/BugRow.tsx | 4 | ||||
-rw-r--r-- | webui/src/pages/list/ListQuery.tsx | 2 |
11 files changed, 175 insertions, 105 deletions
diff --git a/webui/src/pages/bug/LabelChange.tsx b/webui/src/pages/bug/LabelChange.tsx index 712c33fa..868d8c9b 100644 --- a/webui/src/pages/bug/LabelChange.tsx +++ b/webui/src/pages/bug/LabelChange.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import { Typography } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import Author from 'src/components/Author'; @@ -10,11 +11,12 @@ import { LabelChangeFragment } from './LabelChangeFragment.generated'; const useStyles = makeStyles((theme) => ({ main: { - ...theme.typography.body2, + color: theme.palette.text.secondary, marginLeft: theme.spacing(1) + 40, }, author: { fontWeight: 'bold', + color: theme.palette.text.secondary, }, label: { maxWidth: '50ch', @@ -31,7 +33,7 @@ function LabelChange({ op }: Props) { const { added, removed } = op; const classes = useStyles(); return ( - <div className={classes.main}> + <Typography className={classes.main}> <Author author={op.author} className={classes.author} /> {added.length > 0 && <span> added the </span>} {added.map((label, index) => ( @@ -48,7 +50,7 @@ function LabelChange({ op }: Props) { {added.length + removed.length > 1 && 's'}{' '} </span> <Date date={op.date} /> - </div> + </Typography> ); } diff --git a/webui/src/pages/bug/Message.tsx b/webui/src/pages/bug/Message.tsx index 39b11ccd..808bb525 100644 --- a/webui/src/pages/bug/Message.tsx +++ b/webui/src/pages/bug/Message.tsx @@ -21,6 +21,7 @@ import MessageHistoryDialog from './MessageHistoryDialog'; const useStyles = makeStyles((theme) => ({ author: { fontWeight: 'bold', + color: theme.palette.info.contrastText, }, container: { display: 'flex', diff --git a/webui/src/pages/bug/SetStatus.tsx b/webui/src/pages/bug/SetStatus.tsx index 855848f9..f231b917 100644 --- a/webui/src/pages/bug/SetStatus.tsx +++ b/webui/src/pages/bug/SetStatus.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import { Typography } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import { Status } from '../../gqlTypes'; @@ -10,11 +11,12 @@ import { SetStatusFragment } from './SetStatusFragment.generated'; const useStyles = makeStyles((theme) => ({ main: { - ...theme.typography.body2, + color: theme.palette.text.secondary, marginLeft: theme.spacing(1) + 40, }, author: { fontWeight: 'bold', + color: theme.palette.text.secondary, }, })); @@ -29,11 +31,11 @@ function SetStatus({ op }: Props) { ]; return ( - <div className={classes.main}> + <Typography className={classes.main}> <Author author={op.author} className={classes.author} /> <span> {status} this </span> <Date date={op.date} /> - </div> + </Typography> ); } diff --git a/webui/src/pages/bug/SetTitle.tsx b/webui/src/pages/bug/SetTitle.tsx index 98bea928..057062f7 100644 --- a/webui/src/pages/bug/SetTitle.tsx +++ b/webui/src/pages/bug/SetTitle.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import { Typography } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import Author from 'src/components/Author'; @@ -9,11 +10,12 @@ import { SetTitleFragment } from './SetTitleFragment.generated'; const useStyles = makeStyles((theme) => ({ main: { - ...theme.typography.body2, + color: theme.palette.text.secondary, marginLeft: theme.spacing(1) + 40, }, author: { fontWeight: 'bold', + color: theme.palette.text.secondary, }, before: { fontWeight: 'bold', @@ -31,14 +33,14 @@ type Props = { function SetTitle({ op }: Props) { const classes = useStyles(); return ( - <div className={classes.main}> + <Typography className={classes.main}> <Author author={op.author} className={classes.author} /> <span> changed the title from </span> <span className={classes.before}>{op.was}</span> <span> to </span> <span className={classes.after}>{op.title}</span> <Date date={op.date} /> - </div> + </Typography> ); } diff --git a/webui/src/pages/identity/BugList.tsx b/webui/src/pages/identity/BugList.tsx index e74c11d4..c7994827 100644 --- a/webui/src/pages/identity/BugList.tsx +++ b/webui/src/pages/identity/BugList.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { Card, Link, Typography } from '@material-ui/core'; +import { Card, Divider, Link, Typography } from '@material-ui/core'; import CircularProgress from '@material-ui/core/CircularProgress'; import { makeStyles } from '@material-ui/core/styles'; @@ -53,6 +53,7 @@ function BugList({ humanId }: Props) { {bug.title} </Link> </Typography> + <Divider /> <Typography variant="subtitle2"> Created <Date date={bug.createdAt} /> @@ -64,6 +65,7 @@ function BugList({ humanId }: Props) { </Card> ); })} + {bugs?.length === 0 && <p>No authored bugs by this user found.</p>} </div> ); } diff --git a/webui/src/pages/identity/GetUserStatistic.graphql b/webui/src/pages/identity/GetUserStatistic.graphql new file mode 100644 index 00000000..318b860d --- /dev/null +++ b/webui/src/pages/identity/GetUserStatistic.graphql @@ -0,0 +1,13 @@ +query GetUserStatistic($authorQuery: String!, $participantQuery: String!, $actionQuery: String!) { + repository { + authored: allBugs(query: $authorQuery) { + totalCount + }, + participated: allBugs(query: $participantQuery) { + totalCount + } + actions: allBugs(query: $actionQuery) { + totalCount + } + } +} diff --git a/webui/src/pages/identity/Identity.tsx b/webui/src/pages/identity/Identity.tsx index 8261c0f4..5bfc87c0 100644 --- a/webui/src/pages/identity/Identity.tsx +++ b/webui/src/pages/identity/Identity.tsx @@ -1,124 +1,145 @@ import React from 'react'; +import { Link as RouterLink } from 'react-router-dom'; -import { - Checkbox, - FormControlLabel, - Link, - Paper, - Typography, -} from '@material-ui/core'; +import { Link, Paper, Typography } from '@material-ui/core'; import Avatar from '@material-ui/core/Avatar'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import Grid from '@material-ui/core/Grid'; import { makeStyles } from '@material-ui/core/styles'; import InfoIcon from '@material-ui/icons/Info'; import MailOutlineIcon from '@material-ui/icons/MailOutline'; -import { useCurrentIdentityQuery } from '../../components/CurrentIdentity/CurrentIdentity.generated'; +import { IdentityFragment } from '../../components/Identity/IdentityFragment.generated'; -import BugList from './BugList'; +import { useGetUserStatisticQuery } from './GetUserStatistic.generated'; const useStyles = makeStyles((theme) => ({ main: { maxWidth: 1000, margin: 'auto', - marginTop: theme.spacing(4), - padding: theme.spacing(3, 2), - display: 'flex', - }, - container: { - display: 'flex', - marginBottom: theme.spacing(1), - }, - leftSidebar: { - marginTop: theme.spacing(2), - flex: '0 0 200px', + marginTop: theme.spacing(3), }, content: { - marginTop: theme.spacing(5), - padding: theme.spacing(3, 2), - minWidth: 800, - backgroundColor: theme.palette.background.paper, - }, - rightSidebar: { - marginTop: theme.spacing(5), - flex: '0 0 200px', + padding: theme.spacing(0.5, 2, 2, 2), + wordWrap: 'break-word', }, large: { - width: theme.spacing(20), - height: theme.spacing(20), + minWidth: 200, + minHeight: 200, + margin: 'auto', + maxWidth: '100%', + maxHeight: '100%', }, - control: { - paddingBottom: theme.spacing(3), + heading: { + marginTop: theme.spacing(3), }, header: { ...theme.typography.h4, + wordBreak: 'break-word', + }, + infoIcon: { + verticalAlign: 'bottom', }, })); -const Identity = () => { +type Props = { + identity: IdentityFragment; +}; +const Identity = ({ identity }: Props) => { const classes = useStyles(); - const { data } = useCurrentIdentityQuery(); - const user = data?.repository?.userIdentity; - console.log(user); + const user = identity; + + const { loading, error, data } = useGetUserStatisticQuery({ + variables: { + authorQuery: 'author:' + user?.humanId, + participantQuery: 'participant:' + user?.humanId, + actionQuery: 'actor:' + user?.humanId, + }, + }); + + if (loading) return <CircularProgress />; + if (error) return <p>Error: {error}</p>; + const statistic = data?.repository; + const authoredCount = statistic?.authored?.totalCount; + const participatedCount = statistic?.participated?.totalCount; + const actionCount = statistic?.actions?.totalCount; return ( <main className={classes.main}> - <div className={classes.container}> - <div className={classes.leftSidebar}> - <h1 className={classes.header}> - {user?.displayName ? user?.displayName : 'none'} - </h1> - <Avatar - src={user?.avatarUrl ? user.avatarUrl : undefined} - className={classes.large} - > - {user?.displayName.charAt(0).toUpperCase()} - </Avatar> - <Typography variant="h5" component="h2"> - Your account - </Typography> - <Typography variant="subtitle2" component="h2"> - Name: {user?.name ? user?.name : '---'} - </Typography> - <Typography variant="subtitle2" component="h3"> - Id (truncated): {user?.humanId ? user?.humanId : '---'} - <InfoIcon - fontSize={'small'} - titleAccess={user?.id ? user?.id : '---'} - /> - </Typography> - <Typography variant="subtitle2" component="h3"> - Login: {user?.login ? user?.login : '---'} - </Typography> - <Typography - variant="subtitle2" - component="h3" - style={{ - display: 'flex', - alignItems: 'center', - flexWrap: 'wrap', - }} - > - <MailOutlineIcon /> - <Link href={'mailto:' + user?.email} color={'inherit'}> - {user?.email ? user?.email : '---'} - </Link> - </Typography> - <FormControlLabel - className={classes.control} - label="Protected" - labelPlacement="end" - value={user?.isProtected} - control={<Checkbox color="secondary" indeterminate />} - /> - </div> - <Paper className={classes.content}> - <Typography variant="h5" component="h2"> - Bugs authored by {user?.displayName} - </Typography> - <BugList humanId={user?.humanId ? user?.humanId : ''} /> - </Paper> - <div className={classes.rightSidebar}></div> - </div> + <Paper elevation={3} className={classes.content}> + <Grid spacing={2} container direction="row"> + <Grid xs={12} sm={4} className={classes.heading} item> + <Avatar + src={user?.avatarUrl ? user.avatarUrl : undefined} + className={classes.large} + > + {user?.displayName.charAt(0).toUpperCase()} + </Avatar> + </Grid> + <Grid xs={12} sm={4} item> + <section> + <h1 className={classes.header}>{user?.name}</h1> + <Typography variant="subtitle1"> + Name: {user?.displayName ? user?.displayName : '---'} + </Typography> + <Typography variant="subtitle1"> + Id (truncated): {user?.humanId ? user?.humanId : '---'} + <InfoIcon + titleAccess={user?.id ? user?.id : '---'} + className={classes.infoIcon} + /> + </Typography> + {user?.email && ( + <Typography + variant="subtitle1" + style={{ + display: 'flex', + alignItems: 'center', + flexWrap: 'wrap', + }} + > + <MailOutlineIcon /> + <Link href={'mailto:' + user?.email} color={'inherit'}> + {user?.email} + </Link> + </Typography> + )} + </section> + </Grid> + <Grid xs={12} sm={4} item> + <section> + <h1 className={classes.header}>Statistics</h1> + <Link + component={RouterLink} + to={`/?q=author%3A${user?.humanId}+sort%3Acreation`} + color={'inherit'} + > + <Typography variant="subtitle1"> + Created {authoredCount} bugs. + </Typography> + </Link> + <Link + component={RouterLink} + to={`/?q=participant%3A${user?.humanId}+sort%3Acreation`} + color={'inherit'} + > + <Typography variant="subtitle1"> + Participated to {participatedCount} bugs. + </Typography> + </Link> + <Link + component={RouterLink} + to={`/?q=actor%3A${user?.humanId}+sort%3Acreation`} + color={'inherit'} + > + <Typography variant="subtitle1"> + Interacted with {actionCount} bugs. + </Typography> + </Link> + </section> + </Grid> + </Grid> + </Paper> </main> ); }; diff --git a/webui/src/pages/identity/IdentityQuery.tsx b/webui/src/pages/identity/IdentityQuery.tsx new file mode 100644 index 00000000..964a9bac --- /dev/null +++ b/webui/src/pages/identity/IdentityQuery.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { RouteComponentProps } from 'react-router-dom'; + +import CircularProgress from '@material-ui/core/CircularProgress'; + +import { useGetUserByIdQuery } from '../../components/Identity/UserIdentity.generated'; + +import Identity from './Identity'; + +type Props = RouteComponentProps<{ + id: string; +}>; + +const UserQuery: React.FC<Props> = ({ match }: Props) => { + const { loading, error, data } = useGetUserByIdQuery({ + variables: { userId: match.params.id }, + }); + if (loading) return <CircularProgress />; + if (error) return <p>Error: {error}</p>; + if (!data?.repository?.identity) return <p>404.</p>; + return <Identity identity={data.repository.identity} />; +}; + +export default UserQuery; diff --git a/webui/src/pages/identity/index.tsx b/webui/src/pages/identity/index.tsx new file mode 100644 index 00000000..06208687 --- /dev/null +++ b/webui/src/pages/identity/index.tsx @@ -0,0 +1 @@ +export { default } from './IdentityQuery'; diff --git a/webui/src/pages/list/BugRow.tsx b/webui/src/pages/list/BugRow.tsx index 87e45581..a1466d63 100644 --- a/webui/src/pages/list/BugRow.tsx +++ b/webui/src/pages/list/BugRow.tsx @@ -9,6 +9,7 @@ import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline'; import CommentOutlinedIcon from '@material-ui/icons/CommentOutlined'; import ErrorOutline from '@material-ui/icons/ErrorOutline'; +import Author from 'src/components/Author'; import Date from 'src/components/Date'; import Label from 'src/components/Label'; import { Status } from 'src/gqlTypes'; @@ -117,7 +118,8 @@ function BugRow({ bug }: Props) { <div className={classes.details}> {bug.humanId} opened <Date date={bug.createdAt} /> - by {bug.author.displayName} + by + <Author className={classes.details} author={bug.author} /> </div> </div> <span className={classes.commentCountCell}> diff --git a/webui/src/pages/list/ListQuery.tsx b/webui/src/pages/list/ListQuery.tsx index 2b46dca5..9aefd02d 100644 --- a/webui/src/pages/list/ListQuery.tsx +++ b/webui/src/pages/list/ListQuery.tsx @@ -14,7 +14,7 @@ import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'; import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'; import Skeleton from '@material-ui/lab/Skeleton'; -import { useCurrentIdentityQuery } from '../../components/CurrentIdentity/CurrentIdentity.generated'; +import { useCurrentIdentityQuery } from '../../components/Identity/CurrentIdentity.generated'; import IfLoggedIn from 'src/components/IfLoggedIn/IfLoggedIn'; import { parse, Query, stringify } from './Filter'; |