aboutsummaryrefslogtreecommitdiffstats
path: root/webui/src/bug
diff options
context:
space:
mode:
Diffstat (limited to 'webui/src/bug')
-rw-r--r--webui/src/bug/Bug.graphql13
-rw-r--r--webui/src/bug/Bug.tsx97
-rw-r--r--webui/src/bug/BugQuery.graphql9
-rw-r--r--webui/src/bug/BugQuery.tsx22
-rw-r--r--webui/src/bug/CommentForm.graphql5
-rw-r--r--webui/src/bug/CommentForm.tsx145
-rw-r--r--webui/src/bug/LabelChange.tsx49
-rw-r--r--webui/src/bug/LabelChangeFragment.graphql12
-rw-r--r--webui/src/bug/Message.tsx78
-rw-r--r--webui/src/bug/MessageCommentFragment.graphql8
-rw-r--r--webui/src/bug/MessageCreateFragment.graphql8
-rw-r--r--webui/src/bug/SetStatus.tsx31
-rw-r--r--webui/src/bug/SetStatusFragment.graphql7
-rw-r--r--webui/src/bug/SetTitle.tsx37
-rw-r--r--webui/src/bug/SetTitleFragment.graphql8
-rw-r--r--webui/src/bug/Timeline.tsx48
-rw-r--r--webui/src/bug/TimelineQuery.graphql39
-rw-r--r--webui/src/bug/TimelineQuery.tsx30
18 files changed, 0 insertions, 646 deletions
diff --git a/webui/src/bug/Bug.graphql b/webui/src/bug/Bug.graphql
deleted file mode 100644
index 498242c0..00000000
--- a/webui/src/bug/Bug.graphql
+++ /dev/null
@@ -1,13 +0,0 @@
-#import "../components/fragments.graphql"
-
-fragment Bug on Bug {
- id
- humanId
- status
- title
- labels {
- ...Label
- }
- createdAt
- ...authored
-}
diff --git a/webui/src/bug/Bug.tsx b/webui/src/bug/Bug.tsx
deleted file mode 100644
index 0e53e447..00000000
--- a/webui/src/bug/Bug.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-import Typography from '@material-ui/core/Typography/Typography';
-import { makeStyles } from '@material-ui/core/styles';
-import React from 'react';
-
-import Author from '../components/Author';
-import Date from '../components/Date';
-import Label from '../components/Label';
-
-import { BugFragment } from './Bug.generated';
-import CommentForm from './CommentForm';
-import TimelineQuery from './TimelineQuery';
-
-const useStyles = makeStyles(theme => ({
- main: {
- maxWidth: 800,
- margin: 'auto',
- marginTop: theme.spacing(4),
- },
- header: {
- marginLeft: theme.spacing(1) + 40,
- },
- title: {
- ...theme.typography.h5,
- },
- id: {
- ...theme.typography.subtitle1,
- marginLeft: theme.spacing(1),
- },
- container: {
- display: 'flex',
- marginBottom: theme.spacing(1),
- },
- timeline: {
- flex: 1,
- marginTop: theme.spacing(2),
- marginRight: theme.spacing(2),
- minWidth: 0,
- },
- sidebar: {
- marginTop: theme.spacing(2),
- flex: '0 0 200px',
- },
- labelList: {
- listStyle: 'none',
- padding: 0,
- margin: 0,
- },
- label: {
- marginTop: theme.spacing(1),
- marginBottom: theme.spacing(1),
- '& > *': {
- display: 'block',
- },
- },
-}));
-
-type Props = {
- bug: BugFragment;
-};
-
-function Bug({ bug }: Props) {
- const classes = useStyles();
- return (
- <main className={classes.main}>
- <div className={classes.header}>
- <span className={classes.title}>{bug.title}</span>
- <span className={classes.id}>{bug.humanId}</span>
-
- <Typography color={'textSecondary'}>
- <Author author={bug.author} />
- {' opened this bug '}
- <Date date={bug.createdAt} />
- </Typography>
- </div>
-
- <div className={classes.container}>
- <div className={classes.timeline}>
- <TimelineQuery id={bug.id} />
- </div>
- <div className={classes.sidebar}>
- <Typography variant={'subtitle1'}>Labels</Typography>
- <ul className={classes.labelList}>
- {bug.labels.map(l => (
- <li className={classes.label} key={l.name}>
- <Label label={l} key={l.name} />
- </li>
- ))}
- </ul>
- </div>
- </div>
-
- <CommentForm bugId={bug.id} />
- </main>
- );
-}
-
-export default Bug;
diff --git a/webui/src/bug/BugQuery.graphql b/webui/src/bug/BugQuery.graphql
deleted file mode 100644
index cdc4723f..00000000
--- a/webui/src/bug/BugQuery.graphql
+++ /dev/null
@@ -1,9 +0,0 @@
-#import "./Bug.graphql"
-
-query GetBug($id: String!) {
- repository {
- bug(prefix: $id) {
- ...Bug
- }
- }
-}
diff --git a/webui/src/bug/BugQuery.tsx b/webui/src/bug/BugQuery.tsx
deleted file mode 100644
index 2ecf718c..00000000
--- a/webui/src/bug/BugQuery.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import CircularProgress from '@material-ui/core/CircularProgress';
-import React from 'react';
-import { RouteComponentProps } from 'react-router-dom';
-
-import Bug from './Bug';
-import { useGetBugQuery } from './BugQuery.generated';
-
-type Props = RouteComponentProps<{
- id: string;
-}>;
-
-const BugQuery: React.FC<Props> = ({ match }: Props) => {
- const { loading, error, data } = useGetBugQuery({
- variables: { id: match.params.id },
- });
- if (loading) return <CircularProgress />;
- if (error) return <p>Error: {error}</p>;
- if (!data?.repository?.bug) return <p>404.</p>;
- return <Bug bug={data.repository.bug} />;
-};
-
-export default BugQuery;
diff --git a/webui/src/bug/CommentForm.graphql b/webui/src/bug/CommentForm.graphql
deleted file mode 100644
index 33d21193..00000000
--- a/webui/src/bug/CommentForm.graphql
+++ /dev/null
@@ -1,5 +0,0 @@
-mutation AddComment($input: AddCommentInput!) {
- addComment(input: $input) {
- operation { id }
- }
-}
diff --git a/webui/src/bug/CommentForm.tsx b/webui/src/bug/CommentForm.tsx
deleted file mode 100644
index a915ecf0..00000000
--- a/webui/src/bug/CommentForm.tsx
+++ /dev/null
@@ -1,145 +0,0 @@
-import Button from '@material-ui/core/Button';
-import Paper from '@material-ui/core/Paper';
-import Tab from '@material-ui/core/Tab';
-import Tabs from '@material-ui/core/Tabs';
-import TextField from '@material-ui/core/TextField';
-import { makeStyles, Theme } from '@material-ui/core/styles';
-import React, { useState, useRef } from 'react';
-
-import Content from '../components/Content';
-
-import { useAddCommentMutation } from './CommentForm.generated';
-import { TimelineDocument } from './TimelineQuery.generated';
-
-type StyleProps = { loading: boolean };
-const useStyles = makeStyles<Theme, StyleProps>(theme => ({
- container: {
- margin: theme.spacing(2, 0),
- padding: theme.spacing(0, 2, 2, 2),
- },
- textarea: {},
- tabContent: {
- margin: theme.spacing(2, 0),
- },
- preview: {
- borderBottom: `solid 3px ${theme.palette.grey['200']}`,
- minHeight: '5rem',
- },
- actions: {
- display: 'flex',
- justifyContent: 'flex-end',
- },
-}));
-
-type TabPanelProps = {
- children: React.ReactNode;
- value: number;
- index: number;
-} & React.HTMLProps<HTMLDivElement>;
-function TabPanel({ children, value, index, ...props }: TabPanelProps) {
- return (
- <div
- role="tabpanel"
- hidden={value !== index}
- id={`editor-tabpanel-${index}`}
- aria-labelledby={`editor-tab-${index}`}
- {...props}
- >
- {value === index && children}
- </div>
- );
-}
-
-const a11yProps = (index: number) => ({
- id: `editor-tab-${index}`,
- 'aria-controls': `editor-tabpanel-${index}`,
-});
-
-type Props = {
- bugId: string;
-};
-
-function CommentForm({ bugId }: Props) {
- const [addComment, { loading }] = useAddCommentMutation();
- const [input, setInput] = useState<string>('');
- const [tab, setTab] = useState(0);
- const classes = useStyles({ loading });
- const form = useRef<HTMLFormElement>(null);
-
- const submit = () => {
- addComment({
- variables: {
- input: {
- prefix: bugId,
- message: input,
- },
- },
- refetchQueries: [
- // TODO: update the cache instead of refetching
- {
- query: TimelineDocument,
- variables: {
- id: bugId,
- first: 100,
- },
- },
- ],
- awaitRefetchQueries: true,
- }).then(() => setInput(''));
- };
-
- const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
- e.preventDefault();
- submit();
- };
-
- const handleKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {
- // Submit on cmd/ctrl+enter
- if ((e.metaKey || e.altKey) && e.keyCode === 13) {
- submit();
- }
- };
-
- return (
- <Paper className={classes.container}>
- <form onSubmit={handleSubmit} ref={form}>
- <Tabs value={tab} onChange={(_, t) => setTab(t)}>
- <Tab label="Write" {...a11yProps(0)} />
- <Tab label="Preview" {...a11yProps(1)} />
- </Tabs>
- <div className={classes.tabContent}>
- <TabPanel value={tab} index={0}>
- <TextField
- onKeyDown={handleKeyDown}
- fullWidth
- label="Comment"
- placeholder="Leave a comment"
- className={classes.textarea}
- multiline
- value={input}
- variant="filled"
- rows="4" // TODO: rowsMin support
- onChange={(e: any) => setInput(e.target.value)}
- disabled={loading}
- />
- </TabPanel>
- <TabPanel value={tab} index={1} className={classes.preview}>
- <Content markdown={input} />
- </TabPanel>
- </div>
- <div className={classes.actions}>
- <Button
- variant="contained"
- color="primary"
- type="submit"
- disabled={loading}
- >
- Comment
- </Button>
- </div>
- </form>
- </Paper>
- );
-}
-
-export default CommentForm;
diff --git a/webui/src/bug/LabelChange.tsx b/webui/src/bug/LabelChange.tsx
deleted file mode 100644
index a3950524..00000000
--- a/webui/src/bug/LabelChange.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import { makeStyles } from '@material-ui/core/styles';
-import React from 'react';
-
-import Author from '../components/Author';
-import Date from '../components/Date';
-import Label from '../components/Label';
-
-import { LabelChangeFragment } from './LabelChangeFragment.generated';
-
-const useStyles = makeStyles(theme => ({
- main: {
- ...theme.typography.body1,
- marginLeft: theme.spacing(1) + 40,
- },
- author: {
- fontWeight: 'bold',
- },
-}));
-
-type Props = {
- op: LabelChangeFragment;
-};
-
-function LabelChange({ op }: Props) {
- const { added, removed } = op;
- const classes = useStyles();
- return (
- <div className={classes.main}>
- <Author author={op.author} className={classes.author} />
- {added.length > 0 && <span> added the </span>}
- {added.map((label, index) => (
- <Label key={index} label={label} />
- ))}
- {added.length > 0 && removed.length > 0 && <span> and</span>}
- {removed.length > 0 && <span> removed the </span>}
- {removed.map((label, index) => (
- <Label key={index} label={label} />
- ))}
- <span>
- {' '}
- label
- {added.length + removed.length > 1 && 's'}{' '}
- </span>
- <Date date={op.date} />
- </div>
- );
-}
-
-export default LabelChange;
diff --git a/webui/src/bug/LabelChangeFragment.graphql b/webui/src/bug/LabelChangeFragment.graphql
deleted file mode 100644
index 01b94a98..00000000
--- a/webui/src/bug/LabelChangeFragment.graphql
+++ /dev/null
@@ -1,12 +0,0 @@
-#import "../components/fragments.graphql"
-
-fragment LabelChange on LabelChangeTimelineItem {
- date
- ...authored
- added {
- ...Label
- }
- removed {
- ...Label
- }
-}
diff --git a/webui/src/bug/Message.tsx b/webui/src/bug/Message.tsx
deleted file mode 100644
index a61ed3f2..00000000
--- a/webui/src/bug/Message.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import Paper from '@material-ui/core/Paper';
-import { makeStyles } from '@material-ui/core/styles';
-import React from 'react';
-
-import Author, { Avatar } from '../components/Author';
-import Date from '../components/Date';
-import Content from '../components/Content';
-
-import { AddCommentFragment } from './MessageCommentFragment.generated';
-import { CreateFragment } from './MessageCreateFragment.generated';
-
-const useStyles = makeStyles(theme => ({
- author: {
- fontWeight: 'bold',
- },
- container: {
- display: 'flex',
- },
- avatar: {
- marginTop: 2,
- },
- bubble: {
- flex: 1,
- marginLeft: theme.spacing(1),
- minWidth: 0,
- },
- header: {
- ...theme.typography.body1,
- 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',
- },
- body: {
- ...theme.typography.body2,
- padding: '0 1rem',
- },
-}));
-
-type Props = {
- op: AddCommentFragment | CreateFragment;
-};
-
-function Message({ op }: Props) {
- const classes = useStyles();
- return (
- <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}>
- <Content markdown={op.message} />
- </section>
- </Paper>
- </article>
- );
-}
-
-export default Message;
diff --git a/webui/src/bug/MessageCommentFragment.graphql b/webui/src/bug/MessageCommentFragment.graphql
deleted file mode 100644
index 61156fee..00000000
--- a/webui/src/bug/MessageCommentFragment.graphql
+++ /dev/null
@@ -1,8 +0,0 @@
-#import "../components/fragments.graphql"
-
-fragment AddComment on AddCommentTimelineItem {
- createdAt
- ...authored
- edited
- message
-}
diff --git a/webui/src/bug/MessageCreateFragment.graphql b/webui/src/bug/MessageCreateFragment.graphql
deleted file mode 100644
index e371b9dc..00000000
--- a/webui/src/bug/MessageCreateFragment.graphql
+++ /dev/null
@@ -1,8 +0,0 @@
-#import "../components/fragments.graphql"
-
-fragment Create on CreateTimelineItem {
- createdAt
- ...authored
- edited
- message
-}
diff --git a/webui/src/bug/SetStatus.tsx b/webui/src/bug/SetStatus.tsx
deleted file mode 100644
index 86105c8a..00000000
--- a/webui/src/bug/SetStatus.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { makeStyles } from '@material-ui/core/styles';
-import React from 'react';
-
-import Author from '../components/Author';
-import Date from '../components/Date';
-
-import { SetStatusFragment } from './SetStatusFragment.generated';
-
-const useStyles = makeStyles(theme => ({
- main: {
- ...theme.typography.body1,
- marginLeft: theme.spacing(1) + 40,
- },
-}));
-
-type Props = {
- op: SetStatusFragment;
-};
-
-function SetStatus({ op }: Props) {
- const classes = useStyles();
- return (
- <div className={classes.main}>
- <Author author={op.author} bold />
- <span> {op.status.toLowerCase()} this</span>
- <Date date={op.date} />
- </div>
- );
-}
-
-export default SetStatus;
diff --git a/webui/src/bug/SetStatusFragment.graphql b/webui/src/bug/SetStatusFragment.graphql
deleted file mode 100644
index 5a3986d0..00000000
--- a/webui/src/bug/SetStatusFragment.graphql
+++ /dev/null
@@ -1,7 +0,0 @@
-#import "../components/fragments.graphql"
-
-fragment SetStatus on SetStatusTimelineItem {
- date
- ...authored
- status
-}
diff --git a/webui/src/bug/SetTitle.tsx b/webui/src/bug/SetTitle.tsx
deleted file mode 100644
index e57aaafb..00000000
--- a/webui/src/bug/SetTitle.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { makeStyles } from '@material-ui/core/styles';
-import React from 'react';
-
-import Author from '../components/Author';
-import Date from '../components/Date';
-
-import { SetTitleFragment } from './SetTitleFragment.generated';
-
-const useStyles = makeStyles(theme => ({
- main: {
- ...theme.typography.body1,
- marginLeft: theme.spacing(1) + 40,
- },
- bold: {
- fontWeight: 'bold',
- },
-}));
-
-type Props = {
- op: SetTitleFragment;
-};
-
-function SetTitle({ op }: Props) {
- const classes = useStyles();
- return (
- <div className={classes.main}>
- <Author author={op.author} className={classes.bold} />
- <span> changed the title from </span>
- <span className={classes.bold}>{op.was}</span>
- <span> to </span>
- <span className={classes.bold}>{op.title}</span>
- <Date date={op.date} />
- </div>
- );
-}
-
-export default SetTitle;
diff --git a/webui/src/bug/SetTitleFragment.graphql b/webui/src/bug/SetTitleFragment.graphql
deleted file mode 100644
index 22d2185c..00000000
--- a/webui/src/bug/SetTitleFragment.graphql
+++ /dev/null
@@ -1,8 +0,0 @@
-#import "../components/fragments.graphql"
-
-fragment SetTitle on SetTitleTimelineItem {
- date
- ...authored
- title
- was
-}
diff --git a/webui/src/bug/Timeline.tsx b/webui/src/bug/Timeline.tsx
deleted file mode 100644
index ba0f9fc7..00000000
--- a/webui/src/bug/Timeline.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { makeStyles } from '@material-ui/core/styles';
-import React from 'react';
-
-import LabelChange from './LabelChange';
-import Message from './Message';
-import SetStatus from './SetStatus';
-import SetTitle from './SetTitle';
-import { TimelineItemFragment } from './TimelineQuery.generated';
-
-const useStyles = makeStyles(theme => ({
- main: {
- '& > *:not(:last-child)': {
- marginBottom: theme.spacing(2),
- },
- },
-}));
-
-type Props = {
- ops: Array<TimelineItemFragment>;
-};
-
-function Timeline({ ops }: Props) {
- const classes = useStyles();
-
- return (
- <div className={classes.main}>
- {ops.map((op, index) => {
- switch (op.__typename) {
- case 'CreateTimelineItem':
- return <Message key={index} op={op} />;
- case 'AddCommentTimelineItem':
- return <Message key={index} op={op} />;
- case 'LabelChangeTimelineItem':
- return <LabelChange key={index} op={op} />;
- case 'SetTitleTimelineItem':
- return <SetTitle key={index} op={op} />;
- case 'SetStatusTimelineItem':
- return <SetStatus key={index} op={op} />;
- }
-
- console.warn('unsupported operation type ' + op.__typename);
- return null;
- })}
- </div>
- );
-}
-
-export default Timeline;
diff --git a/webui/src/bug/TimelineQuery.graphql b/webui/src/bug/TimelineQuery.graphql
deleted file mode 100644
index 6d78ab7f..00000000
--- a/webui/src/bug/TimelineQuery.graphql
+++ /dev/null
@@ -1,39 +0,0 @@
-#import "./MessageCreateFragment.graphql"
-#import "./MessageCommentFragment.graphql"
-#import "./LabelChangeFragment.graphql"
-#import "./SetTitleFragment.graphql"
-#import "./SetStatusFragment.graphql"
-
-query Timeline($id: String!, $first: Int = 10, $after: String) {
- repository {
- bug(prefix: $id) {
- timeline(first: $first, after: $after) {
- nodes {
- ...TimelineItem
- }
- pageInfo {
- hasNextPage
- endCursor
- }
- }
- }
- }
-}
-
-fragment TimelineItem on TimelineItem {
- ... on LabelChangeTimelineItem {
- ...LabelChange
- }
- ... on SetStatusTimelineItem {
- ...SetStatus
- }
- ... on SetTitleTimelineItem {
- ...SetTitle
- }
- ... on AddCommentTimelineItem {
- ...AddComment
- }
- ... on CreateTimelineItem {
- ...Create
- }
-}
diff --git a/webui/src/bug/TimelineQuery.tsx b/webui/src/bug/TimelineQuery.tsx
deleted file mode 100644
index 9c4cf183..00000000
--- a/webui/src/bug/TimelineQuery.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import CircularProgress from '@material-ui/core/CircularProgress';
-import React from 'react';
-
-import Timeline from './Timeline';
-import { useTimelineQuery } from './TimelineQuery.generated';
-
-type Props = {
- id: string;
-};
-
-const TimelineQuery = ({ id }: Props) => {
- const { loading, error, data } = useTimelineQuery({
- variables: {
- id,
- first: 100,
- },
- });
-
- if (loading) return <CircularProgress />;
- if (error) return <p>Error: {error}</p>;
-
- const nodes = data?.repository?.bug?.timeline.nodes;
- if (!nodes) {
- return null;
- }
-
- return <Timeline ops={nodes} />;
-};
-
-export default TimelineQuery;