Skip to content

Commit

Permalink
feat: header and sidebar improvement (#116)
Browse files Browse the repository at this point in the history
* feat: turn left banner into a foldable drawer

* feat: add breadcrumbs to the header

* feat: persist the sidebar status in localStorage

* fix: header title without BreadCrumb should grow to occupy

* feat: "Dashboard" breadcrumb for /repos
  • Loading branch information
pionxzh authored Dec 3, 2022
1 parent 0f2c6e7 commit 2b93901
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 136 deletions.
31 changes: 15 additions & 16 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,23 @@ const theme = createTheme({
},
});

function NormalLayout({ children }: any) {
type NormalLayoutProps = {
currentPage?: string | null;
children: React.ReactNode;
};

const NormalLayout: React.FC<NormalLayoutProps> = ({
currentPage,
children,
}) => {
return (
<Box>
<Header />
<Header currentPage={currentPage} />
<Box pt="50px">{children}</Box>
{/* <Footer /> */}
</Box>
);
}
};

const router = createBrowserRouter([
{
Expand All @@ -55,25 +63,16 @@ const router = createBrowserRouter([
{
path: "repos",
element: (
<NormalLayout>
<NormalLayout currentPage="Dashboard">
<Repos />
</NormalLayout>
),
},
{
path: "repo/:id",
element: (
<Box height="100vh">
<Header />
<Box
height="100%"
boxSizing={"border-box"}
sx={{
pt: "50px",
}}
>
<Repo />
</Box>
<Box height="100vh" width="100%" boxSizing={"border-box"}>
<Repo />
</Box>
),
},
Expand All @@ -96,7 +95,7 @@ const router = createBrowserRouter([
{
path: "profile",
element: (
<NormalLayout>
<NormalLayout currentPage="Profile">
<Profile />
</NormalLayout>
),
Expand Down
85 changes: 55 additions & 30 deletions ui/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link as ReactLink } from "react-router-dom";
import { Link as ReactLink, useLocation } from "react-router-dom";

import { useState } from "react";

Expand All @@ -9,6 +9,7 @@ import MenuIcon from "@mui/icons-material/Menu";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import Avatar from "@mui/material/Avatar";
import Breadcrumbs from "@mui/material/Breadcrumbs";
import Link from "@mui/material/Link";
import Button from "@mui/material/Button";

Expand All @@ -24,7 +25,49 @@ import { useAuth } from "../lib/auth";

import useMe from "../lib/me";

export function Header() {
type HeaderTitleProps = {
currentPage: string | null;
};

const HeaderTitle: React.FC<HeaderTitleProps> = ({ currentPage = null }) => {
if (!currentPage) {
return (
<Typography variant="h6" sx={{ display: "flex", flexGrow: 1 }}>
<Link component={ReactLink} underline="none" to="/">
CodePod
</Link>
</Typography>
);
}

return (
<Breadcrumbs
aria-label="breadcrumb"
sx={{
alignItems: "baseline",
display: "flex",
flexGrow: 1,
}}
>
<Link component={ReactLink} underline="hover" to="/">
<Typography noWrap>CodePod</Typography>
</Link>
<Typography color="text.primary">{currentPage}</Typography>
</Breadcrumbs>
);
};

type HeaderProps = {
open?: boolean;
drawerWidth?: number;
currentPage?: string | null;
};

export const Header: React.FC<HeaderProps> = ({
open = false,
drawerWidth = 0,
currentPage = null,
}) => {
const [anchorElNav, setAnchorElNav] = useState(null);
const [anchorElUser, setAnchorElUser] = useState(null);

Expand All @@ -48,7 +91,14 @@ export function Header() {
const { me } = useMe();

return (
<AppBar position="fixed" color="inherit">
<AppBar
position="fixed"
color="inherit"
sx={{
width: `calc(100% - ${open ? drawerWidth : 0}px)`,
transition: "width 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
}}
>
<Container maxWidth="xl">
<Toolbar
disableGutters
Expand All @@ -57,17 +107,6 @@ export function Header() {
maxHeight: "10px",
}}
>
<Typography
variant="h6"
noWrap
component="div"
sx={{ mr: 2, display: { xs: "none", md: "flex" } }}
>
<Link component={ReactLink} underline="none" to="/">
CodePod
</Link>
</Typography>

<Box sx={{ flexGrow: 1, display: { xs: "flex", md: "none" } }}>
<IconButton
size="large"
Expand All @@ -93,9 +132,6 @@ export function Header() {
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
sx={{
display: { xs: "block", md: "none" },
}}
>
{/* The toggle menu */}
<MenuItem onClick={handleCloseNavMenu}>
Expand All @@ -120,22 +156,11 @@ export function Header() {
</MenuItem>
</Menu>
</Box>
<Typography
variant="h6"
noWrap
component="div"
color="primary"
sx={{ flexGrow: 1, display: { xs: "flex", md: "none" } }}
>
<Link component={ReactLink} underline="none" to="/">
CodePod
</Link>
</Typography>
<HeaderTitle currentPage={currentPage} />

{/* The navigation on desktop */}
<Box
sx={{
flexGrow: 1,
display: { xs: "none", md: "flex" },
alignItems: "center",
}}
Expand Down Expand Up @@ -186,7 +211,7 @@ export function Header() {
</Container>
</AppBar>
);
}
};

const MyMenuItem = ({ children, to = "/" }) => {
return (
Expand Down
140 changes: 101 additions & 39 deletions ui/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
import { useEffect, useState, useContext } from "react";

import { useEffect, useContext } from "react";
import { useParams } from "react-router-dom";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Divider from "@mui/material/Divider";
import Tooltip from "@mui/material/Tooltip";
import IconButton from "@mui/material/IconButton";

import { grey } from "@mui/material/colors";

import { useSnackbar, VariantType } from "notistack";

import { gql, useQuery, useMutation, useApolloClient } from "@apollo/client";

import StopIcon from "@mui/icons-material/Stop";
import RefreshIcon from "@mui/icons-material/Refresh";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import Drawer from "@mui/material/Drawer";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import Grid from "@mui/material/Grid";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import { useSnackbar, VariantType } from "notistack";

import { gql, useQuery, useMutation, useApolloClient } from "@apollo/client";
import { useStore } from "zustand";

import { usePrompt } from "../lib/prompt";

import { RepoContext, selectNumDirty, RoleType } from "../lib/store";

import useMe from "../lib/me";
import { Grid } from "@mui/material";

function Flex(props) {
return (
Expand Down Expand Up @@ -270,40 +267,105 @@ function ToastError() {
return <Box></Box>;
}

export function Sidebar() {
type SidebarProps = {
width: number;
open: boolean;
onOpen: () => void;
onClose: () => void;
};

export const Sidebar: React.FC<SidebarProps> = ({
width,
open,
onOpen,
onClose,
}) => {
// never render saving status / runtime module for a guest
// FIXME: improve the implementation logic
const store = useContext(RepoContext);
if (!store) throw new Error("Missing BearContext.Provider in the tree");
const role = useStore(store, (state) => state.role);
return (
<Grid container spacing={2}>
{role === RoleType.GUEST ? (
<>
<Grid item xs={12}>
<Box> Read-only Mode: You are a guest. </Box>
</Grid>
<Grid item xs={12}>
{" "}
<SidebarSession />
</Grid>
</>
) : (
<>
<Grid item xs={12}>
<SyncStatus />
</Grid>
<Grid item xs={12}>
{" "}
<SidebarSession />
</Grid>
<Grid item xs={12}>
<SidebarRuntime />
<SidebarKernel />
<>
<Box
sx={{
position: "absolute",
display: open ? "none" : "block",
top: `54px`,
left: 1,
}}
>
<IconButton
onClick={onOpen}
sx={{
zIndex: 1,
}}
>
<ChevronRightIcon />
</IconButton>
</Box>

<Drawer
sx={{
width: width,
flexShrink: 0,
"& .MuiDrawer-paper": {
width: width,
boxSizing: "border-box",
},
}}
variant="persistent"
anchor="left"
open={open}
>
<Box
sx={{
display: "flex",
alignItems: "center",
paddingLeft: "8px",
height: 48,
}}
>
<IconButton onClick={onClose}>
<ChevronLeftIcon />
</IconButton>
</Box>
<Divider />
<Box
sx={{
padding: "8px 16px",
}}
>
<Grid container spacing={2}>
{role === RoleType.GUEST ? (
<>
<Grid item xs={12}>
<Box> Read-only Mode: You are a guest. </Box>
</Grid>
<Grid item xs={12}>
{" "}
<SidebarSession />
</Grid>
</>
) : (
<>
<Grid item xs={12}>
<SyncStatus />
</Grid>
<Grid item xs={12}>
{" "}
<SidebarSession />
</Grid>
<Grid item xs={12}>
<SidebarRuntime />
<SidebarKernel />
</Grid>
<ToastError />
</>
)}
</Grid>
<ToastError />
</>
)}
</Grid>
</Box>
</Drawer>
</>
);
}
};
Loading

0 comments on commit 2b93901

Please sign in to comment.