diff --git a/scm-ui/.vscode/launch.json b/scm-ui/.vscode/launch.json new file mode 100644 index 0000000000..489c044be5 --- /dev/null +++ b/scm-ui/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}/src" + } + ] +} diff --git a/scm-ui/README.md b/scm-ui/README.md index af0586949e..3527f84d73 100644 --- a/scm-ui/README.md +++ b/scm-ui/README.md @@ -6,10 +6,14 @@ * Flow Language Support * Prettier - Code formatter * Project Snippets +* Debugger for Chrome ```bash code --install-extension EditorConfig.EditorConfig code --install-extension flowtype.flow-for-vscode code --install-extension esbenp.prettier-vscode code --install-extension rebornix.project-snippets + +# debugging with chrome browser +code --install-extension msjsdiag.debugger-for-chrome ``` diff --git a/scm-ui/src/apiclient.js b/scm-ui/src/apiclient.js index 7326e78820..bcddf040aa 100644 --- a/scm-ui/src/apiclient.js +++ b/scm-ui/src/apiclient.js @@ -3,8 +3,8 @@ // get api base url from environment const apiUrl = process.env.API_URL || process.env.PUBLIC_URL || "/scm"; -export const PAGE_NOT_FOUND_ERROR = Error("page not found"); -export const NOT_AUTHENTICATED_ERROR = Error("not authenticated"); +export const NOT_FOUND_ERROR = Error("not found"); +export const UNAUTHORIZED_ERROR = Error("unauthorized"); const fetchOptions: RequestOptions = { credentials: "same-origin", @@ -16,10 +16,10 @@ const fetchOptions: RequestOptions = { function handleStatusCode(response: Response) { if (!response.ok) { if (response.status === 401) { - throw NOT_AUTHENTICATED_ERROR; + throw UNAUTHORIZED_ERROR; } if (response.status === 404) { - throw PAGE_NOT_FOUND_ERROR; + throw NOT_FOUND_ERROR; } throw new Error("server returned status code " + response.status); } diff --git a/scm-ui/src/components/ErrorNotification.js b/scm-ui/src/components/ErrorNotification.js index a10ceea6a3..d90caf22a2 100644 --- a/scm-ui/src/components/ErrorNotification.js +++ b/scm-ui/src/components/ErrorNotification.js @@ -3,7 +3,7 @@ import React from "react"; import Notification from "./Notification"; type Props = { - error: Error + error?: Error }; class ErrorNotification extends React.Component { diff --git a/scm-ui/src/components/Footer.js b/scm-ui/src/components/Footer.js index 6673b77949..fd17c06d8b 100644 --- a/scm-ui/src/components/Footer.js +++ b/scm-ui/src/components/Footer.js @@ -3,15 +3,19 @@ import React from "react"; import type { Me } from "../types/me"; type Props = { - me: Me + me?: Me }; class Footer extends React.Component { render() { + const { me } = this.props; + if (!me) { + return ""; + } return (
-

{this.props.me.username}

+

{me.username}

); diff --git a/scm-ui/src/components/PrimaryNavigation.js b/scm-ui/src/components/PrimaryNavigation.js index a66d796a4d..3eda2a2937 100644 --- a/scm-ui/src/components/PrimaryNavigation.js +++ b/scm-ui/src/components/PrimaryNavigation.js @@ -1,11 +1,8 @@ //@flow import React from "react"; import PrimaryNavigationLink from "./PrimaryNavigationLink"; -import PrimaryNavigationAction from "./PrimaryNavigationAction"; -type Props = { - onLogout: () => void -}; +type Props = {}; class PrimaryNavigation extends React.Component { render() { @@ -13,10 +10,7 @@ class PrimaryNavigation extends React.Component { ); diff --git a/scm-ui/src/components/PrimaryNavigationAction.js b/scm-ui/src/components/PrimaryNavigationAction.js deleted file mode 100644 index bf5b91ad2b..0000000000 --- a/scm-ui/src/components/PrimaryNavigationAction.js +++ /dev/null @@ -1,20 +0,0 @@ -//@flow -import * as React from "react"; - -type Props = { - label: string, - onClick: () => void -}; - -class PrimaryNavigationAction extends React.Component { - render() { - const { label, onClick } = this.props; - return ( -
  • - {label} -
  • - ); - } -} - -export default PrimaryNavigationAction; diff --git a/scm-ui/src/components/ProtectedRoute.js b/scm-ui/src/components/ProtectedRoute.js new file mode 100644 index 0000000000..a71f23edf6 --- /dev/null +++ b/scm-ui/src/components/ProtectedRoute.js @@ -0,0 +1,39 @@ +//@flow +import React, { Component } from "react"; +import { Route, Redirect, withRouter } from "react-router-dom"; + +type Props = { + authenticated?: boolean, + component: Component +}; + +class ProtectedRoute extends React.Component { + renderRoute = (Component: any, authenticated?: boolean) => { + return (routeProps: any) => { + if (authenticated) { + return ; + } else { + return ( + + ); + } + }; + }; + + render() { + const { component, authenticated, ...routeProps } = this.props; + return ( + + ); + } +} + +export default withRouter(ProtectedRoute); diff --git a/scm-ui/src/components/SubmitButton.js b/scm-ui/src/components/SubmitButton.js index d4ebdf476c..e022d74155 100644 --- a/scm-ui/src/components/SubmitButton.js +++ b/scm-ui/src/components/SubmitButton.js @@ -22,7 +22,6 @@ class SubmitButton extends React.Component {