webui: move pages components

Quentin Gliech created

Change summary

webui/.eslintrc.js                                 |  6 +
webui/src/App.tsx                                  | 65 +--------------
webui/src/__tests__/query.ts                       |  2 
webui/src/apollo.ts                                | 18 ++++
webui/src/components/Author.tsx                    |  3 
webui/src/components/Content/ImageTag.tsx          |  3 
webui/src/components/Content/PreTag.tsx            |  3 
webui/src/components/Date.tsx                      |  3 
webui/src/components/Label.tsx                     |  6 
webui/src/index.tsx                                | 29 +-----
webui/src/layout/CurrentIdentity.graphql           |  0 
webui/src/layout/CurrentIdentity.tsx               |  3 
webui/src/layout/Header.tsx                        | 50 ++++++++++++
webui/src/layout/index.tsx                         | 18 ++++
webui/src/pages/bug/Bug.graphql                    |  0 
webui/src/pages/bug/Bug.tsx                        |  9 +
webui/src/pages/bug/BugQuery.graphql               |  0 
webui/src/pages/bug/BugQuery.tsx                   |  3 
webui/src/pages/bug/CommentForm.graphql            |  0 
webui/src/pages/bug/CommentForm.tsx                |  5 
webui/src/pages/bug/LabelChange.tsx                |  9 +
webui/src/pages/bug/LabelChangeFragment.graphql    |  2 
webui/src/pages/bug/Message.tsx                    |  9 +
webui/src/pages/bug/MessageCommentFragment.graphql |  2 
webui/src/pages/bug/MessageCreateFragment.graphql  |  2 
webui/src/pages/bug/SetStatus.tsx                  |  7 
webui/src/pages/bug/SetStatusFragment.graphql      |  2 
webui/src/pages/bug/SetTitle.tsx                   |  7 
webui/src/pages/bug/SetTitleFragment.graphql       |  2 
webui/src/pages/bug/Timeline.tsx                   |  3 
webui/src/pages/bug/TimelineQuery.graphql          |  0 
webui/src/pages/bug/TimelineQuery.tsx              |  3 
webui/src/pages/bug/index.tsx                      |  1 
webui/src/pages/list/BugRow.graphql                |  2 
webui/src/pages/list/BugRow.tsx                    | 11 +-
webui/src/pages/list/Filter.tsx                    |  9 +
webui/src/pages/list/FilterToolbar.graphql         |  0 
webui/src/pages/list/FilterToolbar.tsx             |  5 
webui/src/pages/list/List.tsx                      |  3 
webui/src/pages/list/ListQuery.graphql             |  0 
webui/src/pages/list/ListQuery.tsx                 |  7 
webui/src/pages/list/index.ts                      |  1 
webui/src/theme.ts                                 | 11 ++
webui/tsconfig.json                                | 16 +++
44 files changed, 203 insertions(+), 137 deletions(-)

Detailed changes

webui/.eslintrc.js πŸ”—

@@ -29,9 +29,13 @@ module.exports = {
             position: 'after',
           },
         ],
-        groups: [['builtin', 'external'], 'parent', ['sibling', 'index']],
+        pathGroupsExcludedImportTypes: ["builtin"],
+        groups: [['builtin', 'external'], ['internal', 'parent'], ['sibling', 'index']],
         'newlines-between': 'always',
       },
     ],
   },
+  settings: {
+    'import/internal-regex': '^src/',
+  },
 };

webui/src/App.tsx πŸ”—

@@ -1,68 +1,17 @@
-import AppBar from '@material-ui/core/AppBar';
-import CssBaseline from '@material-ui/core/CssBaseline';
-import Toolbar from '@material-ui/core/Toolbar';
-import {
-  createMuiTheme,
-  ThemeProvider,
-  makeStyles,
-} from '@material-ui/core/styles';
 import React from 'react';
 import { Route, Switch } from 'react-router';
-import { Link } from 'react-router-dom';
 
-import CurrentIdentity from './CurrentIdentity';
-import BugQuery from './bug/BugQuery';
-import ListQuery from './list/ListQuery';
-
-const theme = createMuiTheme({
-  palette: {
-    primary: {
-      main: '#263238',
-    },
-  },
-});
-
-const useStyles = makeStyles(theme => ({
-  offset: {
-    ...theme.mixins.toolbar,
-  },
-  filler: {
-    flexGrow: 1,
-  },
-  appTitle: {
-    ...theme.typography.h6,
-    color: 'white',
-    textDecoration: 'none',
-    display: 'flex',
-    alignItems: 'center',
-  },
-  logo: {
-    height: '42px',
-    marginRight: theme.spacing(2),
-  },
-}));
+import Layout from './layout';
+import BugPage from './pages/bug';
+import ListPage from './pages/list';
 
 export default function App() {
-  const classes = useStyles();
-
   return (
-    <ThemeProvider theme={theme}>
-      <CssBaseline />
-      <AppBar position="fixed" color="primary">
-        <Toolbar>
-          <Link to="/" className={classes.appTitle}>
-            <img src="/logo.svg" className={classes.logo} alt="git-bug" />
-            git-bug
-          </Link>
-          <div className={classes.filler}></div>
-          <CurrentIdentity />
-        </Toolbar>
-      </AppBar>
-      <div className={classes.offset} />
+    <Layout>
       <Switch>
-        <Route path="/" exact component={ListQuery} />
-        <Route path="/bug/:id" exact component={BugQuery} />
+        <Route path="/" exact component={ListPage} />
+        <Route path="/bug/:id" exact component={BugPage} />
       </Switch>
-    </ThemeProvider>
+    </Layout>
   );
 }

webui/src/__tests__/query.ts πŸ”—

@@ -1,4 +1,4 @@
-import { parse, stringify, quote } from '../list/Filter';
+import { parse, stringify, quote } from 'src/pages/list/Filter';
 
 it('parses a simple query', () => {
   expect(parse('foo:bar')).toEqual({

webui/src/apollo.ts πŸ”—

@@ -0,0 +1,18 @@
+import ApolloClient from 'apollo-boost';
+import {
+  IntrospectionFragmentMatcher,
+  InMemoryCache,
+} from 'apollo-cache-inmemory';
+
+import introspectionQueryResultData from './fragmentTypes';
+
+const client = new ApolloClient({
+  uri: '/graphql',
+  cache: new InMemoryCache({
+    fragmentMatcher: new IntrospectionFragmentMatcher({
+      introspectionQueryResultData,
+    }),
+  }),
+});
+
+export default client;

webui/src/components/Author.tsx πŸ”—

@@ -1,6 +1,7 @@
+import React from 'react';
+
 import MAvatar from '@material-ui/core/Avatar';
 import Tooltip from '@material-ui/core/Tooltip/Tooltip';
-import React from 'react';
 
 import { AuthoredFragment } from './fragments.generated';
 

webui/src/components/Content/ImageTag.tsx πŸ”—

@@ -1,6 +1,7 @@
-import { makeStyles } from '@material-ui/styles';
 import React from 'react';
 
+import { makeStyles } from '@material-ui/styles';
+
 const useStyles = makeStyles({
   tag: {
     maxWidth: '100%',

webui/src/components/Content/PreTag.tsx πŸ”—

@@ -1,6 +1,7 @@
-import { makeStyles } from '@material-ui/styles';
 import React from 'react';
 
+import { makeStyles } from '@material-ui/styles';
+
 const useStyles = makeStyles({
   tag: {
     maxWidth: '100%',

webui/src/components/Date.tsx πŸ”—

@@ -1,8 +1,9 @@
-import Tooltip from '@material-ui/core/Tooltip/Tooltip';
 import moment from 'moment';
 import React from 'react';
 import Moment from 'react-moment';
 
+import Tooltip from '@material-ui/core/Tooltip/Tooltip';
+
 const HOUR = 1000 * 3600;
 const DAY = 24 * HOUR;
 const WEEK = 7 * DAY;

webui/src/components/Label.tsx πŸ”—

@@ -1,13 +1,15 @@
+import React from 'react';
+
 import { common } from '@material-ui/core/colors';
 import { makeStyles } from '@material-ui/core/styles';
 import {
   getContrastRatio,
   darken,
 } from '@material-ui/core/styles/colorManipulator';
-import React from 'react';
+
+import { Color } from 'src/gqlTypes';
 
 import { LabelFragment } from './fragments.generated';
-import { Color } from '../gqlTypes';
 
 // Minimum contrast between the background and the text color
 const contrastThreshold = 2.5;

webui/src/index.tsx πŸ”—

@@ -1,36 +1,19 @@
-import { createMuiTheme } from '@material-ui/core/styles';
-import ThemeProvider from '@material-ui/styles/ThemeProvider';
-import ApolloClient from 'apollo-boost';
-import {
-  IntrospectionFragmentMatcher,
-  InMemoryCache,
-} from 'apollo-cache-inmemory';
 import React from 'react';
 import { ApolloProvider } from 'react-apollo';
 import ReactDOM from 'react-dom';
 import { BrowserRouter } from 'react-router-dom';
 
-import App from './App';
-import introspectionQueryResultData from './fragmentTypes';
-
-const theme = createMuiTheme();
+import ThemeProvider from '@material-ui/styles/ThemeProvider';
 
-const client = new ApolloClient({
-  uri: '/graphql',
-  cache: new InMemoryCache({
-    fragmentMatcher: new IntrospectionFragmentMatcher({
-      introspectionQueryResultData,
-    }),
-  }),
-});
+import App from './App';
+import apolloClient from './apollo';
+import theme from './theme';
 
 ReactDOM.render(
-  <ApolloProvider client={client}>
+  <ApolloProvider client={apolloClient}>
     <BrowserRouter>
       <ThemeProvider theme={theme}>
-        <React.Suspense fallback={'Loading…'}>
-          <App />
-        </React.Suspense>
+        <App />
       </ThemeProvider>
     </BrowserRouter>
   </ApolloProvider>,

webui/src/CurrentIdentity.tsx β†’ webui/src/layout/CurrentIdentity.tsx πŸ”—

@@ -1,6 +1,7 @@
+import React from 'react';
+
 import Avatar from '@material-ui/core/Avatar';
 import { makeStyles } from '@material-ui/core/styles';
-import React from 'react';
 
 import { useCurrentIdentityQuery } from './CurrentIdentity.generated';
 

webui/src/layout/Header.tsx πŸ”—

@@ -0,0 +1,50 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+
+import AppBar from '@material-ui/core/AppBar';
+import Toolbar from '@material-ui/core/Toolbar';
+import { makeStyles } from '@material-ui/core/styles';
+
+import CurrentIdentity from './CurrentIdentity';
+
+const useStyles = makeStyles(theme => ({
+  offset: {
+    ...theme.mixins.toolbar,
+  },
+  filler: {
+    flexGrow: 1,
+  },
+  appTitle: {
+    ...theme.typography.h6,
+    color: 'white',
+    textDecoration: 'none',
+    display: 'flex',
+    alignItems: 'center',
+  },
+  logo: {
+    height: '42px',
+    marginRight: theme.spacing(2),
+  },
+}));
+
+function Header() {
+  const classes = useStyles();
+
+  return (
+    <>
+      <AppBar position="fixed" color="primary">
+        <Toolbar>
+          <Link to="/" className={classes.appTitle}>
+            <img src="/logo.svg" className={classes.logo} alt="git-bug" />
+            git-bug
+          </Link>
+          <div className={classes.filler}></div>
+          <CurrentIdentity />
+        </Toolbar>
+      </AppBar>
+      <div className={classes.offset} />
+    </>
+  );
+}
+
+export default Header;

webui/src/layout/index.tsx πŸ”—

@@ -0,0 +1,18 @@
+import React from 'react';
+
+import CssBaseline from '@material-ui/core/CssBaseline';
+
+import Header from './Header';
+
+type Props = { children: React.ReactNode };
+function Layout({ children }: Props) {
+  return (
+    <>
+      <CssBaseline />
+      <Header />
+      {children}
+    </>
+  );
+}
+
+export default Layout;

webui/src/bug/Bug.tsx β†’ webui/src/pages/bug/Bug.tsx πŸ”—

@@ -1,10 +1,11 @@
+import React from 'react';
+
 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 Author from 'src/components/Author';
+import Date from 'src/components/Date';
+import Label from 'src/components/Label';
 
 import { BugFragment } from './Bug.generated';
 import CommentForm from './CommentForm';

webui/src/bug/BugQuery.tsx β†’ webui/src/pages/bug/BugQuery.tsx πŸ”—

@@ -1,7 +1,8 @@
-import CircularProgress from '@material-ui/core/CircularProgress';
 import React from 'react';
 import { RouteComponentProps } from 'react-router-dom';
 
+import CircularProgress from '@material-ui/core/CircularProgress';
+
 import Bug from './Bug';
 import { useGetBugQuery } from './BugQuery.generated';
 

webui/src/bug/CommentForm.tsx β†’ webui/src/pages/bug/CommentForm.tsx πŸ”—

@@ -1,12 +1,13 @@
+import React, { useState, useRef } from 'react';
+
 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 Content from 'src/components/Content';
 
 import { useAddCommentMutation } from './CommentForm.generated';
 import { TimelineDocument } from './TimelineQuery.generated';

webui/src/bug/LabelChange.tsx β†’ webui/src/pages/bug/LabelChange.tsx πŸ”—

@@ -1,9 +1,10 @@
-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 { makeStyles } from '@material-ui/core/styles';
+
+import Author from 'src/components/Author';
+import Date from 'src/components/Date';
+import Label from 'src/components/Label';
 
 import { LabelChangeFragment } from './LabelChangeFragment.generated';
 

webui/src/bug/Message.tsx β†’ webui/src/pages/bug/Message.tsx πŸ”—

@@ -1,10 +1,11 @@
+import React from 'react';
+
 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 Author, { Avatar } from 'src/components/Author';
+import Content from 'src/components/Content';
+import Date from 'src/components/Date';
 
 import { AddCommentFragment } from './MessageCommentFragment.generated';
 import { CreateFragment } from './MessageCreateFragment.generated';

webui/src/bug/SetStatus.tsx β†’ webui/src/pages/bug/SetStatus.tsx πŸ”—

@@ -1,8 +1,9 @@
-import { makeStyles } from '@material-ui/core/styles';
 import React from 'react';
 
-import Author from '../components/Author';
-import Date from '../components/Date';
+import { makeStyles } from '@material-ui/core/styles';
+
+import Author from 'src/components/Author';
+import Date from 'src/components/Date';
 
 import { SetStatusFragment } from './SetStatusFragment.generated';
 

webui/src/bug/SetTitle.tsx β†’ webui/src/pages/bug/SetTitle.tsx πŸ”—

@@ -1,8 +1,9 @@
-import { makeStyles } from '@material-ui/core/styles';
 import React from 'react';
 
-import Author from '../components/Author';
-import Date from '../components/Date';
+import { makeStyles } from '@material-ui/core/styles';
+
+import Author from 'src/components/Author';
+import Date from 'src/components/Date';
 
 import { SetTitleFragment } from './SetTitleFragment.generated';
 

webui/src/bug/Timeline.tsx β†’ webui/src/pages/bug/Timeline.tsx πŸ”—

@@ -1,6 +1,7 @@
-import { makeStyles } from '@material-ui/core/styles';
 import React from 'react';
 
+import { makeStyles } from '@material-ui/core/styles';
+
 import LabelChange from './LabelChange';
 import Message from './Message';
 import SetStatus from './SetStatus';

webui/src/bug/TimelineQuery.tsx β†’ webui/src/pages/bug/TimelineQuery.tsx πŸ”—

@@ -1,6 +1,7 @@
-import CircularProgress from '@material-ui/core/CircularProgress';
 import React from 'react';
 
+import CircularProgress from '@material-ui/core/CircularProgress';
+
 import Timeline from './Timeline';
 import { useTimelineQuery } from './TimelineQuery.generated';
 

webui/src/list/BugRow.graphql β†’ webui/src/pages/list/BugRow.graphql πŸ”—

@@ -1,4 +1,4 @@
-#import "../components/fragments.graphql"
+#import "../../components/fragments.graphql"
 
 fragment BugRow on Bug {
   id

webui/src/list/BugRow.tsx β†’ webui/src/pages/list/BugRow.tsx πŸ”—

@@ -1,15 +1,16 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+
 import TableCell from '@material-ui/core/TableCell/TableCell';
 import TableRow from '@material-ui/core/TableRow/TableRow';
 import Tooltip from '@material-ui/core/Tooltip/Tooltip';
 import { makeStyles } from '@material-ui/core/styles';
 import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline';
 import ErrorOutline from '@material-ui/icons/ErrorOutline';
-import React from 'react';
-import { Link } from 'react-router-dom';
 
-import Date from '../components/Date';
-import Label from '../components/Label';
-import { Status } from '../gqlTypes';
+import Date from 'src/components/Date';
+import Label from 'src/components/Label';
+import { Status } from 'src/gqlTypes';
 
 import { BugRowFragment } from './BugRow.generated';
 

webui/src/list/Filter.tsx β†’ webui/src/pages/list/Filter.tsx πŸ”—

@@ -1,12 +1,13 @@
+import clsx from 'clsx';
+import { LocationDescriptor } from 'history';
+import React, { useState, useRef } from 'react';
+import { Link } from 'react-router-dom';
+
 import Menu from '@material-ui/core/Menu';
 import MenuItem from '@material-ui/core/MenuItem';
 import { SvgIconProps } from '@material-ui/core/SvgIcon';
 import { makeStyles } from '@material-ui/core/styles';
 import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
-import clsx from 'clsx';
-import { LocationDescriptor } from 'history';
-import React, { useState, useRef } from 'react';
-import { Link } from 'react-router-dom';
 
 export type Query = { [key: string]: Array<string> };
 

webui/src/list/FilterToolbar.tsx β†’ webui/src/pages/list/FilterToolbar.tsx πŸ”—

@@ -1,10 +1,11 @@
 import { pipe } from '@arrows/composition';
+import { LocationDescriptor } from 'history';
+import React from 'react';
+
 import Toolbar from '@material-ui/core/Toolbar';
 import { makeStyles } from '@material-ui/core/styles';
 import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline';
 import ErrorOutline from '@material-ui/icons/ErrorOutline';
-import { LocationDescriptor } from 'history';
-import React from 'react';
 
 import {
   FilterDropdown,

webui/src/list/List.tsx β†’ webui/src/pages/list/List.tsx πŸ”—

@@ -1,6 +1,7 @@
+import React from 'react';
+
 import Table from '@material-ui/core/Table/Table';
 import TableBody from '@material-ui/core/TableBody/TableBody';
-import React from 'react';
 
 import BugRow from './BugRow';
 import { BugListFragment } from './ListQuery.generated';

webui/src/list/ListQuery.tsx β†’ webui/src/pages/list/ListQuery.tsx πŸ”—

@@ -1,3 +1,7 @@
+import { ApolloError } from 'apollo-boost';
+import React, { useState, useEffect, useRef } from 'react';
+import { useLocation, useHistory, Link } from 'react-router-dom';
+
 import IconButton from '@material-ui/core/IconButton';
 import InputBase from '@material-ui/core/InputBase';
 import Paper from '@material-ui/core/Paper';
@@ -6,9 +10,6 @@ import ErrorOutline from '@material-ui/icons/ErrorOutline';
 import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft';
 import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight';
 import Skeleton from '@material-ui/lab/Skeleton';
-import { ApolloError } from 'apollo-boost';
-import React, { useState, useEffect, useRef } from 'react';
-import { useLocation, useHistory, Link } from 'react-router-dom';
 
 import FilterToolbar from './FilterToolbar';
 import List from './List';

webui/src/theme.ts πŸ”—

@@ -0,0 +1,11 @@
+import { createMuiTheme } from '@material-ui/core/styles';
+
+const theme = createMuiTheme({
+  palette: {
+    primary: {
+      main: '#263238',
+    },
+  },
+});
+
+export default theme;

webui/tsconfig.json πŸ”—

@@ -1,7 +1,11 @@
 {
   "compilerOptions": {
     "target": "es5",
-    "lib": ["dom", "dom.iterable", "esnext"],
+    "lib": [
+      "dom",
+      "dom.iterable",
+      "esnext"
+    ],
     "allowJs": true,
     "skipLibCheck": true,
     "esModuleInterop": true,
@@ -14,7 +18,13 @@
     "isolatedModules": true,
     "noEmit": true,
     "jsx": "react",
-    "typeRoots": ["node_modules/@types/", "types/"]
+    "typeRoots": [
+      "node_modules/@types/",
+      "types/"
+    ],
+    "baseUrl": "."
   },
-  "include": ["src"]
+  "include": [
+    "src"
+  ]
 }