From d0a6da286a28e79ae3bb75af41219c4cc4df20b0 Mon Sep 17 00:00:00 2001 From: ludovicm67 Date: Wed, 12 Feb 2020 23:09:45 +0100 Subject: webui: finish TypeScript conversion --- webui/codegen.yaml | 16 +++--- webui/src/.gitignore | 2 +- webui/src/Author.tsx | 6 ++- webui/src/bug/LabelChange.js | 43 --------------- webui/src/bug/LabelChange.tsx | 48 +++++++++++++++++ webui/src/bug/LabelChangeFragment.graphql | 18 +++---- webui/src/bug/Message.js | 72 ------------------------- webui/src/bug/Message.tsx | 78 ++++++++++++++++++++++++++++ webui/src/bug/MessageCommentFragment.graphql | 12 ++--- webui/src/bug/MessageCreateFragment.graphql | 12 ++--- webui/src/bug/SetStatus.js | 25 --------- webui/src/bug/SetStatus.tsx | 30 +++++++++++ webui/src/bug/SetStatusFragment.graphql | 10 ++-- webui/src/bug/SetTitle.js | 31 ----------- webui/src/bug/SetTitle.tsx | 36 +++++++++++++ webui/src/bug/SetTitleFragment.graphql | 12 ++--- webui/src/bug/Timeline.js | 44 ---------------- webui/src/bug/Timeline.tsx | 48 +++++++++++++++++ webui/src/bug/TimelineQuery.graphql | 24 +++++++-- webui/src/bug/TimelineQuery.js | 22 -------- webui/src/bug/TimelineQuery.tsx | 30 +++++++++++ 21 files changed, 330 insertions(+), 289 deletions(-) delete mode 100644 webui/src/bug/LabelChange.js create mode 100644 webui/src/bug/LabelChange.tsx delete mode 100644 webui/src/bug/Message.js create mode 100644 webui/src/bug/Message.tsx delete mode 100644 webui/src/bug/SetStatus.js create mode 100644 webui/src/bug/SetStatus.tsx delete mode 100644 webui/src/bug/SetTitle.js create mode 100644 webui/src/bug/SetTitle.tsx delete mode 100644 webui/src/bug/Timeline.js create mode 100644 webui/src/bug/Timeline.tsx delete mode 100644 webui/src/bug/TimelineQuery.js create mode 100644 webui/src/bug/TimelineQuery.tsx diff --git a/webui/codegen.yaml b/webui/codegen.yaml index 1580632e..3cdb0517 100644 --- a/webui/codegen.yaml +++ b/webui/codegen.yaml @@ -2,22 +2,22 @@ schema: '../graphql/schema/*.graphql' overwrite: true documents: src/**/*.graphql generates: - ./src/fragmentTypes.js: + ./src/fragmentTypes.ts: plugins: - - fragment-matcher + - fragment-matcher config: module: es2015 ./src/gqlTypes.ts: plugins: - - typescript + - typescript ./src/schema.json: plugins: - - introspection + - introspection ./src/: plugins: - - add: '/* eslint-disable @typescript-eslint/no-unused-vars, import/order */' - - typescript-operations - - typescript-react-apollo + - add: '/* eslint-disable @typescript-eslint/no-unused-vars, import/order */' + - typescript-operations + - typescript-react-apollo preset: near-operation-file presetConfig: extension: .generated.tsx @@ -29,4 +29,4 @@ generates: hooks: afterAllFileWrite: - - prettier --write + - prettier --write diff --git a/webui/src/.gitignore b/webui/src/.gitignore index 640de4f9..2ef0dba1 100644 --- a/webui/src/.gitignore +++ b/webui/src/.gitignore @@ -1,4 +1,4 @@ -fragmentTypes.js +fragmentTypes.ts gqlTypes.ts *.generated.* schema.json diff --git a/webui/src/Author.tsx b/webui/src/Author.tsx index 20de583a..852cd2b7 100644 --- a/webui/src/Author.tsx +++ b/webui/src/Author.tsx @@ -4,7 +4,11 @@ import React from 'react'; import { AuthoredFragment } from './Author.generated'; -type Props = AuthoredFragment; +type Props = AuthoredFragment & { + className?: string; + bold?: boolean; +}; + const Author = ({ author, ...props }: Props) => { if (!author.email) { return {author.displayName}; diff --git a/webui/src/bug/LabelChange.js b/webui/src/bug/LabelChange.js deleted file mode 100644 index 442cbbb4..00000000 --- a/webui/src/bug/LabelChange.js +++ /dev/null @@ -1,43 +0,0 @@ -import { makeStyles } from '@material-ui/styles'; -import React from 'react'; - -import Author from '../Author'; -import Date from '../Date'; -import Label from '../Label'; - -const useStyles = makeStyles(theme => ({ - main: { - ...theme.typography.body1, - marginLeft: theme.spacing(1) + 40, - }, - author: { - fontWeight: 'bold', - }, -})); - -function LabelChange({ op }) { - const { added, removed } = op; - const classes = useStyles(); - return ( -
- - {added.length > 0 && added the } - {added.map((label, index) => ( -
- ); -} - -export default LabelChange; diff --git a/webui/src/bug/LabelChange.tsx b/webui/src/bug/LabelChange.tsx new file mode 100644 index 00000000..e7c75a37 --- /dev/null +++ b/webui/src/bug/LabelChange.tsx @@ -0,0 +1,48 @@ +import { makeStyles } from '@material-ui/core/styles'; +import React from 'react'; + +import Author from '../Author'; +import Date from '../Date'; +import Label from '../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 ( +
+ + {added.length > 0 && added the } + {added.map((label, index) => ( +
+ ); +} + +export default LabelChange; diff --git a/webui/src/bug/LabelChangeFragment.graphql b/webui/src/bug/LabelChangeFragment.graphql index 07b1d351..631de70c 100644 --- a/webui/src/bug/LabelChangeFragment.graphql +++ b/webui/src/bug/LabelChangeFragment.graphql @@ -1,15 +1,13 @@ #import "../Author.graphql" #import "../Label.graphql" -fragment LabelChange on TimelineItem { - ... on LabelChangeTimelineItem { - date - ...authored - added { - ...Label - } - removed { - ...Label - } +fragment LabelChange on LabelChangeTimelineItem { + date + ...authored + added { + ...Label + } + removed { + ...Label } } diff --git a/webui/src/bug/Message.js b/webui/src/bug/Message.js deleted file mode 100644 index 68d3cea0..00000000 --- a/webui/src/bug/Message.js +++ /dev/null @@ -1,72 +0,0 @@ -import Paper from '@material-ui/core/Paper'; -import { makeStyles } from '@material-ui/styles'; -import React from 'react'; - -import Author from '../Author'; -import { Avatar } from '../Author'; -import Content from '../Content'; -import Date from '../Date'; - -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', - }, -})); - -function Message({ op }) { - const classes = useStyles(); - return ( -
- - -
-
- - commented - -
- {op.edited &&
Edited
} -
-
- -
-
-
- ); -} - -export default Message; diff --git a/webui/src/bug/Message.tsx b/webui/src/bug/Message.tsx new file mode 100644 index 00000000..33e0f1da --- /dev/null +++ b/webui/src/bug/Message.tsx @@ -0,0 +1,78 @@ +import Paper from '@material-ui/core/Paper'; +import { makeStyles } from '@material-ui/core/styles'; +import React from 'react'; + +import Author from '../Author'; +import { Avatar } from '../Author'; +import Content from '../Content'; +import Date from '../Date'; +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 ( +
+ + +
+
+ + commented + +
+ {op.edited &&
Edited
} +
+
+ +
+
+
+ ); +} + +export default Message; diff --git a/webui/src/bug/MessageCommentFragment.graphql b/webui/src/bug/MessageCommentFragment.graphql index 83cc9f61..38d626d0 100644 --- a/webui/src/bug/MessageCommentFragment.graphql +++ b/webui/src/bug/MessageCommentFragment.graphql @@ -1,10 +1,8 @@ #import "../Author.graphql" -fragment AddComment on TimelineItem { - ... on AddCommentTimelineItem { - createdAt - ...authored - edited - message - } +fragment AddComment on AddCommentTimelineItem { + createdAt + ...authored + edited + message } diff --git a/webui/src/bug/MessageCreateFragment.graphql b/webui/src/bug/MessageCreateFragment.graphql index e753444f..08477470 100644 --- a/webui/src/bug/MessageCreateFragment.graphql +++ b/webui/src/bug/MessageCreateFragment.graphql @@ -1,10 +1,8 @@ #import "../Author.graphql" -fragment Create on TimelineItem { - ... on CreateTimelineItem { - createdAt - ...authored - edited - message - } +fragment Create on CreateTimelineItem { + createdAt + ...authored + edited + message } diff --git a/webui/src/bug/SetStatus.js b/webui/src/bug/SetStatus.js deleted file mode 100644 index b6dd419d..00000000 --- a/webui/src/bug/SetStatus.js +++ /dev/null @@ -1,25 +0,0 @@ -import { makeStyles } from '@material-ui/styles'; -import React from 'react'; - -import Author from '../Author'; -import Date from '../Date'; - -const useStyles = makeStyles(theme => ({ - main: { - ...theme.typography.body1, - marginLeft: theme.spacing(1) + 40, - }, -})); - -function SetStatus({ op }) { - const classes = useStyles(); - return ( -
- - {op.status.toLowerCase()} this - -
- ); -} - -export default SetStatus; diff --git a/webui/src/bug/SetStatus.tsx b/webui/src/bug/SetStatus.tsx new file mode 100644 index 00000000..6d51e342 --- /dev/null +++ b/webui/src/bug/SetStatus.tsx @@ -0,0 +1,30 @@ +import { makeStyles } from '@material-ui/core/styles'; +import React from 'react'; + +import Author from '../Author'; +import Date from '../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 ( +
+ + {op.status.toLowerCase()} this + +
+ ); +} + +export default SetStatus; diff --git a/webui/src/bug/SetStatusFragment.graphql b/webui/src/bug/SetStatusFragment.graphql index 56e22c2b..0fdea01b 100644 --- a/webui/src/bug/SetStatusFragment.graphql +++ b/webui/src/bug/SetStatusFragment.graphql @@ -1,9 +1,7 @@ #import "../Author.graphql" -fragment SetStatus on TimelineItem { - ... on SetStatusTimelineItem { - date - ...authored - status - } +fragment SetStatus on SetStatusTimelineItem { + date + ...authored + status } diff --git a/webui/src/bug/SetTitle.js b/webui/src/bug/SetTitle.js deleted file mode 100644 index 09343ad1..00000000 --- a/webui/src/bug/SetTitle.js +++ /dev/null @@ -1,31 +0,0 @@ -import { makeStyles } from '@material-ui/styles'; -import React from 'react'; - -import Author from '../Author'; -import Date from '../Date'; - -const useStyles = makeStyles(theme => ({ - main: { - ...theme.typography.body1, - marginLeft: theme.spacing(1) + 40, - }, - bold: { - fontWeight: 'bold', - }, -})); - -function SetTitle({ op }) { - const classes = useStyles(); - return ( -
- - changed the title from - {op.was} - to - {op.title} - -
- ); -} - -export default SetTitle; diff --git a/webui/src/bug/SetTitle.tsx b/webui/src/bug/SetTitle.tsx new file mode 100644 index 00000000..8a578aa1 --- /dev/null +++ b/webui/src/bug/SetTitle.tsx @@ -0,0 +1,36 @@ +import { makeStyles } from '@material-ui/core/styles'; +import React from 'react'; + +import Author from '../Author'; +import Date from '../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 ( +
+ + changed the title from + {op.was} + to + {op.title} + +
+ ); +} + +export default SetTitle; diff --git a/webui/src/bug/SetTitleFragment.graphql b/webui/src/bug/SetTitleFragment.graphql index a15c3eb3..432c4449 100644 --- a/webui/src/bug/SetTitleFragment.graphql +++ b/webui/src/bug/SetTitleFragment.graphql @@ -1,10 +1,8 @@ #import "../Author.graphql" -fragment SetTitle on TimelineItem { - ... on SetTitleTimelineItem { - date - ...authored - title - was - } +fragment SetTitle on SetTitleTimelineItem { + date + ...authored + title + was } diff --git a/webui/src/bug/Timeline.js b/webui/src/bug/Timeline.js deleted file mode 100644 index aeef7d2b..00000000 --- a/webui/src/bug/Timeline.js +++ /dev/null @@ -1,44 +0,0 @@ -import { makeStyles } from '@material-ui/styles'; -import React from 'react'; - -import LabelChange from './LabelChange'; -import Message from './Message'; -import SetStatus from './SetStatus'; -import SetTitle from './SetTitle'; - -const useStyles = makeStyles(theme => ({ - main: { - '& > *:not(:last-child)': { - marginBottom: theme.spacing(2), - }, - }, -})); - -const componentMap = { - CreateTimelineItem: Message, - AddCommentTimelineItem: Message, - LabelChangeTimelineItem: LabelChange, - SetTitleTimelineItem: SetTitle, - SetStatusTimelineItem: SetStatus, -}; - -function Timeline({ ops }) { - const classes = useStyles(); - - return ( -
- {ops.map((op, index) => { - const Component = componentMap[op.__typename]; - - if (!Component) { - console.warn('unsupported operation type ' + op.__typename); - return null; - } - - return ; - })} -
- ); -} - -export default Timeline; diff --git a/webui/src/bug/Timeline.tsx b/webui/src/bug/Timeline.tsx new file mode 100644 index 00000000..ba0f9fc7 --- /dev/null +++ b/webui/src/bug/Timeline.tsx @@ -0,0 +1,48 @@ +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; +}; + +function Timeline({ ops }: Props) { + const classes = useStyles(); + + return ( +
+ {ops.map((op, index) => { + switch (op.__typename) { + case 'CreateTimelineItem': + return ; + case 'AddCommentTimelineItem': + return ; + case 'LabelChangeTimelineItem': + return ; + case 'SetTitleTimelineItem': + return ; + case 'SetStatusTimelineItem': + return ; + } + + console.warn('unsupported operation type ' + op.__typename); + return null; + })} +
+ ); +} + +export default Timeline; diff --git a/webui/src/bug/TimelineQuery.graphql b/webui/src/bug/TimelineQuery.graphql index 493f4416..6d78ab7f 100644 --- a/webui/src/bug/TimelineQuery.graphql +++ b/webui/src/bug/TimelineQuery.graphql @@ -9,11 +9,7 @@ query Timeline($id: String!, $first: Int = 10, $after: String) { bug(prefix: $id) { timeline(first: $first, after: $after) { nodes { - ...LabelChange - ...SetStatus - ...SetTitle - ...AddComment - ...Create + ...TimelineItem } pageInfo { hasNextPage @@ -23,3 +19,21 @@ query Timeline($id: String!, $first: Int = 10, $after: String) { } } } + +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.js b/webui/src/bug/TimelineQuery.js deleted file mode 100644 index 886edab2..00000000 --- a/webui/src/bug/TimelineQuery.js +++ /dev/null @@ -1,22 +0,0 @@ -import CircularProgress from '@material-ui/core/CircularProgress'; -import React from 'react'; - -import Timeline from './Timeline'; -import { useTimelineQuery } from './TimelineQuery.generated'; - -const TimelineQuery = ({ id }) => { - const { loading, error, data, fetchMore } = useTimelineQuery({ - variables: { - id, - first: 100, - }, - }); - - if (loading) return ; - if (error) return

Error: {error}

; - return ( - - ); -}; - -export default TimelineQuery; diff --git a/webui/src/bug/TimelineQuery.tsx b/webui/src/bug/TimelineQuery.tsx new file mode 100644 index 00000000..9c4cf183 --- /dev/null +++ b/webui/src/bug/TimelineQuery.tsx @@ -0,0 +1,30 @@ +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 ; + if (error) return

Error: {error}

; + + const nodes = data?.repository?.bug?.timeline.nodes; + if (!nodes) { + return null; + } + + return ; +}; + +export default TimelineQuery; -- cgit