diff --git a/webui/public/logo-alpha-flat-outline.svg b/webui/public/logo-alpha-flat-outline.svg new file mode 100644 index 0000000000000000000000000000000000000000..ea383f3c0d4e9730d2393f2dce487e4a823c8624 --- /dev/null +++ b/webui/public/logo-alpha-flat-outline.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/webui/src/App.tsx b/webui/src/App.tsx index b9ade9740258114c868d8ce92cbd55228e26a3c1..4c81913cbdd5b346f62f64830ae34854af22a2d0 100644 --- a/webui/src/App.tsx +++ b/webui/src/App.tsx @@ -5,6 +5,7 @@ import Layout from './components/Header'; import BugPage from './pages/bug'; import ListPage from './pages/list'; import NewBugPage from './pages/new/NewBugPage'; +import NotFoundPage from './pages/notfound/NotFoundPage'; export default function App() { return ( @@ -13,6 +14,7 @@ export default function App() { + ); diff --git a/webui/src/components/BackToListButton.tsx b/webui/src/components/BackToListButton.tsx new file mode 100644 index 0000000000000000000000000000000000000000..7ca53ad05ae8595c7790500d7322d1a0e9aa0d21 --- /dev/null +++ b/webui/src/components/BackToListButton.tsx @@ -0,0 +1,36 @@ +import React from 'react'; + +import Button from '@material-ui/core/Button'; +import { makeStyles } from '@material-ui/core/styles'; +import ArrowBackIcon from '@material-ui/icons/ArrowBack'; + +const useStyles = makeStyles((theme) => ({ + backButton: { + position: 'sticky', + top: '80px', + backgroundColor: theme.palette.primary.dark, + color: theme.palette.primary.contrastText, + '&:hover': { + backgroundColor: theme.palette.primary.main, + color: theme.palette.primary.contrastText, + }, + }, +})); + +function BackToListButton() { + const classes = useStyles(); + + return ( + + ); +} + +export default BackToListButton; diff --git a/webui/src/components/BugTitleForm/BugTitleForm.tsx b/webui/src/components/BugTitleForm/BugTitleForm.tsx index cc9f52675ff7e54f8251e3615c02fa5be19c4dc6..a7d5a820422288e63958d37963a8224eb4a30445 100644 --- a/webui/src/components/BugTitleForm/BugTitleForm.tsx +++ b/webui/src/components/BugTitleForm/BugTitleForm.tsx @@ -70,7 +70,7 @@ function BugTitleForm({ bug }: Props) { function isFormValid() { if (issueTitleInput) { - return issueTitleInput.value.length > 0 ? true : false; + return issueTitleInput.value.length > 0; } else { return false; } diff --git a/webui/src/components/Content/PreTag.tsx b/webui/src/components/Content/PreTag.tsx index 5256ab12ec8abacd56dded3153569d5136f6dac0..8e352153238c927c73c075e59c0eff61f3879991 100644 --- a/webui/src/components/Content/PreTag.tsx +++ b/webui/src/components/Content/PreTag.tsx @@ -11,7 +11,7 @@ const useStyles = makeStyles({ const PreTag = (props: React.HTMLProps) => { const classes = useStyles(); - return
;
+  return 
;
 };
 
 export default PreTag;
diff --git a/webui/src/components/Header/Header.tsx b/webui/src/components/Header/Header.tsx
index 3bdb252f4aa0ef308b5ccc2af4f635b1229c874c..3064f6e458d8a0ac3ebad6ae83ab52aaf22b2d33 100644
--- a/webui/src/components/Header/Header.tsx
+++ b/webui/src/components/Header/Header.tsx
@@ -1,12 +1,15 @@
 import React from 'react';
-import { Link } from 'react-router-dom';
+import { Link, useLocation } from 'react-router-dom';
 
 import AppBar from '@material-ui/core/AppBar';
+import Tab, { TabProps } from '@material-ui/core/Tab';
+import Tabs from '@material-ui/core/Tabs';
 import Toolbar from '@material-ui/core/Toolbar';
+import Tooltip from '@material-ui/core/Tooltip/Tooltip';
 import { makeStyles } from '@material-ui/core/styles';
 
-import { LightSwitch } from '../../components/Themer';
 import CurrentIdentity from '../CurrentIdentity/CurrentIdentity';
+import { LightSwitch } from '../Themer';
 
 const useStyles = makeStyles((theme) => ({
   offset: {
@@ -15,9 +18,13 @@ const useStyles = makeStyles((theme) => ({
   filler: {
     flexGrow: 1,
   },
+  appBar: {
+    backgroundColor: theme.palette.primary.dark,
+    color: theme.palette.primary.contrastText,
+  },
   appTitle: {
     ...theme.typography.h6,
-    color: 'white',
+    color: theme.palette.primary.contrastText,
     textDecoration: 'none',
     display: 'flex',
     alignItems: 'center',
@@ -31,18 +38,53 @@ const useStyles = makeStyles((theme) => ({
   },
 }));
 
+function a11yProps(index: any) {
+  return {
+    id: `nav-tab-${index}`,
+    'aria-controls': `nav-tabpanel-${index}`,
+  };
+}
+
+const DisabledTabWithTooltip = (props: TabProps) => {
+  /*The span elements around disabled tabs are needed, as the tooltip
+   * won't be triggered by disabled elements.
+   * See: https://material-ui.com/components/tooltips/#disabled-elements
+   * This must be done in a wrapper component, otherwise the TabS component
+   * cannot pass it styles down to the Tab component. Resulting in (console)
+   * warnings. This wrapper acceps the passed down TabProps and pass it around
+   * the span element to the Tab component.
+   */
+  const msg = `This feature doesn't exist yet. Come help us build it.`;
+  return (
+    
+      
+        
+      
+    
+  );
+};
+
 function Header() {
   const classes = useStyles();
+  const location = useLocation();
+  const [selectedTab, setTab] = React.useState(location.pathname);
+
+  const handleTabClick = (
+    event: React.ChangeEvent<{}>,
+    newTabValue: string
+  ) => {
+    setTab(newTabValue);
+  };
 
   return (
     <>
-      
+      
         
           
-            git-bug
+            git-bug logo
             git-bug
           
-          
+
@@ -50,6 +92,25 @@ function Header() {
+ + + + + + ); } diff --git a/webui/src/pages/bug/Bug.tsx b/webui/src/pages/bug/Bug.tsx index d85c52966139658fe79ef1d1d9ac7fcdc6a06401..3b6b61e0afcfb4f703937fc53fcd6222e6a47410 100644 --- a/webui/src/pages/bug/Bug.tsx +++ b/webui/src/pages/bug/Bug.tsx @@ -18,11 +18,17 @@ const useStyles = makeStyles((theme) => ({ maxWidth: 1000, margin: 'auto', marginTop: theme.spacing(4), - overflow: 'hidden', }, header: { - marginLeft: theme.spacing(3) + 40, marginRight: theme.spacing(2), + marginLeft: theme.spacing(3) + 40, + }, + title: { + ...theme.typography.h5, + }, + id: { + ...theme.typography.subtitle1, + marginLeft: theme.spacing(1), }, container: { display: 'flex', @@ -36,11 +42,11 @@ const useStyles = makeStyles((theme) => ({ marginRight: theme.spacing(2), minWidth: 400, }, - sidebar: { + rightSidebar: { marginTop: theme.spacing(2), flex: '0 0 200px', }, - sidebarTitle: { + rightSidebarTitle: { fontWeight: 'bold', }, labelList: { @@ -75,7 +81,6 @@ function Bug({ bug }: Props) {
-
@@ -87,8 +92,8 @@ function Bug({ bug }: Props) { )}
-
- Labels +
+ Labels
    {bug.labels.length === 0 && ( None yet diff --git a/webui/src/pages/bug/BugQuery.tsx b/webui/src/pages/bug/BugQuery.tsx index 2a70a2f84f676f29c72837a028cc96f5c9e117b6..5d459c429a737fc812fe7615c629c2684ade06ca 100644 --- a/webui/src/pages/bug/BugQuery.tsx +++ b/webui/src/pages/bug/BugQuery.tsx @@ -3,6 +3,8 @@ import { RouteComponentProps } from 'react-router-dom'; import CircularProgress from '@material-ui/core/CircularProgress'; +import NotFoundPage from '../notfound/NotFoundPage'; + import Bug from './Bug'; import { useGetBugQuery } from './BugQuery.generated'; @@ -15,8 +17,8 @@ const BugQuery: React.FC = ({ match }: Props) => { variables: { id: match.params.id }, }); if (loading) return ; + if (!data?.repository?.bug) return ; if (error) return

    Error: {error}

    ; - if (!data?.repository?.bug) return

    404.

    ; return ; }; diff --git a/webui/src/pages/bug/CommentForm.tsx b/webui/src/pages/bug/CommentForm.tsx index 773e7d0ecd8f6fb40d4176a204078db16240ad2e..6d27e398780cef110d666364f5ec3b2c7eecc510 100644 --- a/webui/src/pages/bug/CommentForm.tsx +++ b/webui/src/pages/bug/CommentForm.tsx @@ -28,6 +28,7 @@ const useStyles = makeStyles((theme) => ({ }, actions: { display: 'flex', + gap: '1em', justifyContent: 'flex-end', }, greenButton: { diff --git a/webui/src/pages/list/FilterToolbar.tsx b/webui/src/pages/list/FilterToolbar.tsx index e4cd8e6a244a338c74d26f073e1c181acb3ac3d8..74eefe4c3184ac27c3b7649576bdccb43d2a16f9 100644 --- a/webui/src/pages/list/FilterToolbar.tsx +++ b/webui/src/pages/list/FilterToolbar.tsx @@ -40,7 +40,7 @@ function CountingFilter({ query, children, ...props }: CountingFilterProps) { variables: { query }, }); - var prefix; + let prefix; if (loading) prefix = '...'; else if (error || !data?.repository) prefix = '???'; // TODO: better prefixes & error handling diff --git a/webui/src/pages/new/NewBugPage.tsx b/webui/src/pages/new/NewBugPage.tsx index 96afb56a8a1d05720f7272e65d36f4429c21e62b..4dc60e3c0ae26eff7e0fbecf3e591d4b6e58b7cb 100644 --- a/webui/src/pages/new/NewBugPage.tsx +++ b/webui/src/pages/new/NewBugPage.tsx @@ -1,7 +1,7 @@ import React, { FormEvent, useState } from 'react'; +import { useHistory } from 'react-router-dom'; -import { Button } from '@material-ui/core'; -import Paper from '@material-ui/core/Paper'; +import { Button, Paper } from '@material-ui/core'; import { makeStyles, Theme } from '@material-ui/core/styles'; import BugTitleInput from '../../components/BugTitleForm/BugTitleInput'; @@ -47,7 +47,9 @@ function NewBugPage() { const [issueTitle, setIssueTitle] = useState(''); const [issueComment, setIssueComment] = useState(''); const classes = useStyles(); + let issueTitleInput: any; + let history = useHistory(); function submitNewIssue(e: FormEvent) { e.preventDefault(); @@ -59,12 +61,15 @@ function NewBugPage() { message: issueComment, }, }, + }).then(function (data) { + const id = data.data?.newBug.bug.humanId; + history.push('/bug/' + id); }); issueTitleInput.value = ''; } function isFormValid() { - return issueTitle.length > 0 && issueComment.length > 0 ? true : false; + return issueTitle.length > 0; } if (loading) return
    Loading...
    ; diff --git a/webui/src/pages/notfound/NotFoundPage.tsx b/webui/src/pages/notfound/NotFoundPage.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2c6f68540029055944c15cb4ee4e758d3c1c197a --- /dev/null +++ b/webui/src/pages/notfound/NotFoundPage.tsx @@ -0,0 +1,52 @@ +import React from 'react'; + +import { makeStyles } from '@material-ui/core/styles'; + +import BackToListButton from '../../components/BackToListButton'; + +const useStyles = makeStyles((theme) => ({ + main: { + maxWidth: 1000, + margin: 'auto', + marginTop: theme.spacing(10), + }, + logo: { + height: '350px', + display: 'block', + marginLeft: 'auto', + marginRight: 'auto', + }, + icon: { + display: 'block', + marginLeft: 'auto', + marginRight: 'auto', + fontSize: '80px', + }, + backLink: { + marginTop: theme.spacing(1), + textAlign: 'center', + }, + header: { + fontSize: '30px', + textAlign: 'center', + }, +})); + +function NotFoundPage() { + const classes = useStyles(); + return ( +
    +

    404 – Page not found

    + git-bug Logo +
    + +
    +
    + ); +} + +export default NotFoundPage; diff --git a/webui/src/themes/DefaultDark.ts b/webui/src/themes/DefaultDark.ts index 6a92ec49df522346db64a2228165c7ec8ba760fd..65dd6329b44ed0b334d21c8bce712efc3b715844 100644 --- a/webui/src/themes/DefaultDark.ts +++ b/webui/src/themes/DefaultDark.ts @@ -4,7 +4,8 @@ const defaultDarkTheme = createMuiTheme({ palette: { type: 'dark', primary: { - main: '#263238', + dark: '#263238', + main: '#2a393e', light: '#525252', }, error: { diff --git a/webui/src/themes/DefaultLight.ts b/webui/src/themes/DefaultLight.ts index bc788a986634e35ca9682a05808f6d292da39867..9c57ebe57ce904a8df3f346848c219784ff7d595 100644 --- a/webui/src/themes/DefaultLight.ts +++ b/webui/src/themes/DefaultLight.ts @@ -4,8 +4,10 @@ const defaultLightTheme = createMuiTheme({ palette: { type: 'light', primary: { - main: '#263238', + dark: '#263238', + main: '#5a6b73', light: '#f5f5f5', + contrastText: '#fff', }, info: { main: '#e2f1ff',