Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Centralize the AppBar; Remove extraneous component wrappers #807

Merged
merged 11 commits into from
Nov 15, 2020
4 changes: 2 additions & 2 deletions src/backend/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import axios from "axios";

import authHeader from "../components/Login/AuthHeaders";
import history, { path } from "../history";
import history, { Path } from "../history";
import { Goal, GoalType } from "../types/goals";
import { Project } from "../types/project";
import { RuntimeConfig } from "../types/runtimeConfig";
Expand All @@ -28,7 +28,7 @@ backendServer.interceptors.response.use(
},
(err) => {
if (err.response && err.response.status === 401) {
history.push(path.login);
history.push(Path.Login);
}
return Promise.reject(err);
}
Expand Down
32 changes: 16 additions & 16 deletions src/backend/localStorage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,58 @@ import { Hash } from "../goals/MergeDupGoal/MergeDupStep/MergeDupsTree";
import { User } from "../types/user";
import { getUser } from ".";

export enum localStorageKeys {
avatar = "avatar",
mergeDupsBlacklist = "mergeDupsBlacklist",
projectId = "projectId",
user = "user",
export enum LocalStorageKey {
Avatar = "avatar",
MergeDupsBlacklist = "mergeDupsBlacklist",
ProjectId = "projectId",
User = "user",
}

// This function should only be used on Logout.
export function clearLocalStorage() {
for (const key in localStorageKeys) {
remove(key as localStorageKeys);
for (const key in LocalStorageKey) {
remove(key as LocalStorageKey);
}
}

export function getAvatar(): string {
return localStorage.getItem(localStorageKeys.avatar) || "";
return localStorage.getItem(LocalStorageKey.Avatar) || "";
}
export function setAvatar(src: string) {
localStorage.setItem(localStorageKeys.avatar, src);
localStorage.setItem(LocalStorageKey.Avatar, src);
}

export function getCurrentUser(): User | null {
const userString: string | null = localStorage.getItem(localStorageKeys.user);
const userString: string | null = localStorage.getItem(LocalStorageKey.User);
return userString ? JSON.parse(userString) : null;
}
export function setCurrentUser(user: User) {
const userString: string = JSON.stringify(user);
localStorage.setItem(localStorageKeys.user, userString);
localStorage.setItem(LocalStorageKey.User, userString);
}

export function getMergeDupsBlacklist(): Hash<boolean> {
const blacklist = localStorage.getItem(localStorageKeys.mergeDupsBlacklist);
const blacklist = localStorage.getItem(LocalStorageKey.MergeDupsBlacklist);
return blacklist ? JSON.parse(blacklist) : {};
}
export function setMergeDupsBlacklist(blacklist: Hash<boolean>) {
const blacklistString = JSON.stringify(blacklist);
localStorage.setItem(localStorageKeys.mergeDupsBlacklist, blacklistString);
localStorage.setItem(LocalStorageKey.MergeDupsBlacklist, blacklistString);
}

export function getProjectId(): string {
return localStorage.getItem(localStorageKeys.projectId) || "";
return localStorage.getItem(LocalStorageKey.ProjectId) || "";
}
export function setProjectId(id: string) {
localStorage.setItem(localStorageKeys.projectId, id);
localStorage.setItem(LocalStorageKey.ProjectId, id);
}

export function getUserId(): string {
const user: User | null = getCurrentUser();
return user ? user.id : "";
}

export function remove(localStorageKey: localStorageKeys) {
export function remove(localStorageKey: LocalStorageKey) {
localStorage.removeItem(localStorageKey);
}

Expand Down
36 changes: 36 additions & 0 deletions src/components/App/AppLoggedIn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { Route, Switch, useLocation } from "react-router-dom";

import { getBasePath, Path } from "../../history";
import AppBar from "../AppBar/AppBarComponent";
import DataEntry from "../DataEntry";
import GoalRoute from "../GoalRoute/component";
import PageNotFound from "../PageNotFound/component";
import ProjectSettings from "../ProjectSettings";
import ProjectScreen from "../ProjectScreen/ProjectScreenComponent";
import SiteSettings from "../SiteSettings/SiteSettingsComponent";
import UserSettings from "../UserSettings/UserSettings";

export default function AppWithBar() {
const location = useLocation();
const [currentLoc, setCurrentLoc] = React.useState<Path>(Path.ProjScreen);

React.useEffect(() => {
setCurrentLoc(getBasePath(location.pathname));
}, [location]);

return (
<React.Fragment>
<AppBar currentTab={currentLoc} />
<Switch>
<Route exact path={Path.ProjScreen} component={ProjectScreen} />
<Route exact path={Path.DataEntry} component={DataEntry} />
<Route exact path={Path.ProjSettings} component={ProjectSettings} />
<Route exact path={Path.SiteSettings} component={SiteSettings} />
<Route exact path={Path.UserSettings} component={UserSettings} />
<Route path={Path.Goals} component={GoalRoute} />
<Route component={PageNotFound} />
</Switch>
</React.Fragment>
);
}
47 changes: 12 additions & 35 deletions src/components/App/component.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
//external modules
import React from "react";
import { Route, Switch } from "react-router-dom";
import { Redirect, Route, Switch } from "react-router-dom";

//TC modules
import { path } from "../../history";
import DataEntry from "../DataEntry";
import GoalRoute from "../GoalRoute/component";
import { Path } from "../../history";
import Login from "../Login/LoginPage";
import Register from "../Login/RegisterPage";
import PageNotFound from "../PageNotFound/component";
import PasswordReset from "../PasswordReset/ResetPage";
import ResetRequest from "../PasswordReset/RequestPage";
import PrivateRoute from "../PrivateRoute";
import ProjectInvite from "../ProjectInvite";
import ProjectScreen from "../ProjectScreen/ProjectScreenComponent";
import ProjectSettings from "../ProjectSettings";
import SiteSettings from "../SiteSettings/SiteSettingsComponent";
import UserSettings from "../UserSettings/UserSettings";
import AppWithBar from "./AppLoggedIn";

/**
* The top-level component
Expand All @@ -26,34 +21,16 @@ export default class App extends React.Component {
return (
<div className="App">
<Switch>
<PrivateRoute
exact
path={path.projScreen}
component={ProjectScreen}
/>
<PrivateRoute exact path={path.dataEntry} component={DataEntry} />
<PrivateRoute
exact
path={path.projSettings}
component={ProjectSettings}
/>
<PrivateRoute
exact
path={path.siteSettings}
component={SiteSettings}
/>
<PrivateRoute
exact
path={path.userSettings}
component={UserSettings}
/>
<PrivateRoute path={path.goals} component={GoalRoute} />
<Route path={path.login} component={Login} />
<Route path={path.register} component={Register} />
<Route path={`${path.pwReset}/:token`} component={PasswordReset} />
<Route path={path.pwRequest} component={ResetRequest} />
<Route exact path={Path.Root}>
<Redirect to={Path.ProjScreen} />
</Route>
<PrivateRoute path={Path.ProjScreen} component={AppWithBar} />
<Route path={Path.Login} component={Login} />
<Route path={Path.Register} component={Register} />
<Route path={`${Path.PwReset}/:token`} component={PasswordReset} />
<Route path={Path.PwRequest} component={ResetRequest} />
<Route
path={`${path.projInvite}/:project/:token`}
path={`${Path.ProjInvite}/:project/:token`}
component={ProjectInvite}
/>
<Route component={PageNotFound} />
Expand Down
89 changes: 38 additions & 51 deletions src/components/AppBar/AppBarComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,47 @@
import { AppBar, Grid, Toolbar } from "@material-ui/core";
import React from "react";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import { withLocalize, LocalizeContextProps } from "react-localize-redux";
import { Grid } from "@material-ui/core";
import UserMenu from "./UserMenu";
import Logo from "./Logo";

import { getProjectId } from "../../backend/localStorage";
import { Path } from "../../history";
import theme from "../../types/theme";
import Logo from "./Logo";
import NavigationButtons from "./NavigationButtons";
import { getProjectId } from "../../backend/localStorage";
import ProjectNameButton from "./ProjectNameButton";
import { CurrentTab } from "../../types/currentTab";
import UserMenu from "./UserMenu";

export interface AppBarComponentProps {
currentTab: CurrentTab;
currentTab: Path;
}

export class AppBarComponent extends React.Component<
AppBarComponentProps & LocalizeContextProps
> {
/** An app bar shown at the top of almost every page of The Combine */
render() {
return (
<React.Fragment>
<div
className="NavigationBar"
style={{ marginBottom: theme.spacing(12) }}
>
<AppBar position="fixed" style={{ zIndex: theme.zIndex.drawer + 1 }}>
<Toolbar>
<Grid
container
justify="space-between"
spacing={2}
alignItems="center"
>
<Grid item xs>
<Logo />
{getProjectId() !== "" && (
<NavigationButtons currentTab={this.props.currentTab} />
)}
</Grid>
<Grid item xs>
{getProjectId() !== "" && (
<ProjectNameButton currentTab={this.props.currentTab} />
)}
</Grid>
<Grid item>
<UserMenu />
</Grid>
</Grid>
</Toolbar>
</AppBar>
</div>
</React.Fragment>
);
}
/** An app bar shown at the top of all logged in pages */
export default function AppBarComponent(props: AppBarComponentProps) {
return (
<div className="NavigationBar" style={{ marginBottom: theme.spacing(12) }}>
<AppBar position="fixed" style={{ zIndex: theme.zIndex.drawer + 1 }}>
<Toolbar>
<Grid
container
justify="space-between"
spacing={2}
alignItems="center"
>
<Grid item xs>
<Logo />
{getProjectId() !== "" && (
<NavigationButtons currentTab={props.currentTab} />
)}
</Grid>
<Grid item xs>
{getProjectId() !== "" && (
<ProjectNameButton currentTab={props.currentTab} />
)}
</Grid>
<Grid item>
<UserMenu />
</Grid>
</Grid>
</Toolbar>
</AppBar>
</div>
);
}

export default withLocalize(AppBarComponent);
4 changes: 2 additions & 2 deletions src/components/AppBar/Logo.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button } from "@material-ui/core";
import React from "react";

import history, { path } from "../../history";
import history, { Path } from "../../history";
import logo from "../../resources/CombineLogoV1.png";
import smallLogo from "../../resources/CombineSmallLogoV1.png";

Expand All @@ -10,7 +10,7 @@ export default function Logo() {
return (
<Button
onClick={() => {
history.push(path.projScreen);
history.push(Path.ProjScreen);
}}
>
<img
Expand Down
14 changes: 7 additions & 7 deletions src/components/AppBar/NavigationButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { Button } from "@material-ui/core";
import React from "react";
import { Translate } from "react-localize-redux";

import history, { path } from "../../history";
import { CurrentTab, tabColor } from "../../types/currentTab";
import history, { Path } from "../../history";
import { tabColor } from "../../types/theme";

interface NavigationButtonsProps {
currentTab: CurrentTab;
currentTab: Path;
}

/** A button that redirects to the home page */
Expand All @@ -16,23 +16,23 @@ export default function NavigationButtons(props: NavigationButtonsProps) {
<Button
id="data-entry"
onClick={() => {
history.push(path.dataEntry);
history.push(Path.DataEntry);
}}
color="inherit"
style={{
background: tabColor(props.currentTab, CurrentTab.DataEntry),
background: tabColor(props.currentTab, Path.DataEntry),
}}
>
<Translate id="appBar.dataEntry" />
</Button>
<Button
id="goals"
onClick={() => {
history.push(path.goals);
history.push(Path.Goals);
}}
color="inherit"
style={{
background: tabColor(props.currentTab, CurrentTab.DataCleanup),
background: tabColor(props.currentTab, Path.Goals),
}}
>
<Translate id="appBar.dataCleanup" />
Expand Down
10 changes: 5 additions & 5 deletions src/components/AppBar/ProjectNameButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { Button } from "@material-ui/core";
import React from "react";
import { useSelector } from "react-redux";

import history, { path } from "../../history";
import { CurrentTab, tabColor } from "../../types/currentTab";
import history, { Path } from "../../history";
import { tabColor } from "../../types/theme";

interface ProjectNameButtonProps {
currentTab: CurrentTab;
currentTab: Path;
}

/** A button that redirects to the project settings */
Expand All @@ -18,11 +18,11 @@ export default function ProjectNameButton(props: ProjectNameButtonProps) {
<Button
id="project-name"
onClick={() => {
history.push(path.projSettings);
history.push(Path.ProjSettings);
}}
color="inherit"
style={{
background: tabColor(props.currentTab, CurrentTab.ProjectSettings),
background: tabColor(props.currentTab, Path.ProjSettings),
}}
>
{projectName}
Expand Down
Loading