Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions src/app/(authed)/(home)/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
"use client"

import { useContext, useEffect } from "react"
import { ProjectsContainerContext } from "@/common"
import DelayedLoadingIndicator from "@/common/ui/DelayedLoadingIndicator"
import { useEffect } from "react"
import ErrorMessage from "@/common/ui/ErrorMessage"
import { updateWindowTitle } from "@/features/projects/domain"
import { useProjectSelection } from "@/features/projects/data"
import Documentation from "@/features/projects/view/Documentation"

export default function Page() {
const { error, isLoading } = useContext(ProjectsContainerContext)
const { project, version, specification, navigateToSelectionIfNeeded } = useProjectSelection()
// Ensure the URL reflects the current selection of project, version, and specification.
useEffect(() => {
Expand All @@ -32,10 +29,6 @@ export default function Page() {
return <ErrorMessage text="The selected branch or tag was not found."/>
} else if (project && !specification) {
return <ErrorMessage text="The selected specification was not found."/>
} else if (isLoading) {
return <DelayedLoadingIndicator/>
} else if (error) {
return <ErrorMessage text={error.message}/>
} else {
// No project is selected so we will not show anything.
return <></>
Expand Down
36 changes: 0 additions & 36 deletions src/app/(authed)/(home)/layout.tsx

This file was deleted.

13 changes: 8 additions & 5 deletions src/app/(authed)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { SessionProvider } from "next-auth/react"
import { session, projectRepository } from "@/composition"
import ErrorHandler from "@/common/ui/ErrorHandler"
import SessionBarrier from "@/features/auth/view/SessionBarrier"
import ServerSideCachedProjectsProvider from "@/features/projects/view/ServerSideCachedProjectsProvider"
import ProjectsContextProvider from "@/features/projects/view/ProjectsContextProvider"
import { SplitView } from "@/features/sidebar/view"

export default async function Layout({ children }: { children: React.ReactNode }) {
const isAuthenticated = await session.getIsAuthenticated()
Expand All @@ -15,11 +16,13 @@ export default async function Layout({ children }: { children: React.ReactNode }
<ErrorHandler>
<SessionProvider>
<SessionBarrier>
<ServerSideCachedProjectsProvider projects={projects}>
{children}
</ServerSideCachedProjectsProvider>
<ProjectsContextProvider initialProjects={projects}>
<SplitView>
{children}
</SplitView>
</ProjectsContextProvider>
</SessionBarrier>
</SessionProvider>
</ErrorHandler>
)
}
}
26 changes: 0 additions & 26 deletions src/app/api/user/projects/route.ts

This file was deleted.

19 changes: 7 additions & 12 deletions src/common/contexts.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
"use client"

import { createContext } from "react"
import { Project, } from "@/features/projects/domain"
import { Project } from "@/features/projects/domain"

export const SidebarContext = createContext<{ isToggleable: boolean }>({ isToggleable: true })

type ProjectsContainer = {
readonly projects: Project[]
readonly isLoading: boolean
readonly error?: Error
type ProjectsContextValue = {
projects: Project[],
setProjects: (projects: Project[]) => void
}

export const ProjectsContainerContext = createContext<ProjectsContainer>({
isLoading: true,
projects: []
export const ProjectsContext = createContext<ProjectsContextValue>({
projects: [],
setProjects: () => {}
})

export const ServerSideCachedProjectsContext = createContext<Project[] | undefined>(undefined)
2 changes: 2 additions & 0 deletions src/common/ui/MenuItemHover.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client"

import { SxProps } from "@mui/system"
import { Box } from "@mui/material"
import useMediaQuery from "@mui/material/useMediaQuery"
Expand Down
1 change: 0 additions & 1 deletion src/features/projects/data/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export { default as GitHubProjectDataSource } from "./GitHubProjectDataSource"
export * from "./GitHubProjectDataSource"
export { default as useProjects } from "./useProjects"
export { default as useProjectSelection } from "./useProjectSelection"
export { default as GitHubLoginDataSource } from "./GitHubLoginDataSource"
export { default as GitHubRepositoryDataSource } from "./GitHubRepositoryDataSource"
4 changes: 2 additions & 2 deletions src/features/projects/data/useProjectSelection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { useRouter, usePathname } from "next/navigation"
import { useContext } from "react"
import useMediaQuery from "@mui/material/useMediaQuery"
import { useTheme } from "@mui/material/styles"
import { ProjectsContainerContext } from "@/common"
import { ProjectsContext } from "@/common"
import { Project, ProjectNavigator, getProjectSelectionFromPath } from "../domain"
import { useSidebarOpen } from "@/features/sidebar/data"

export default function useProjectSelection() {
const router = useRouter()
const pathname = usePathname()
const { projects } = useContext(ProjectsContainerContext)
const { projects } = useContext(ProjectsContext)
const selection = getProjectSelectionFromPath({ projects, path: pathname })
const pathnameReader = {
get pathname() {
Expand Down
19 changes: 0 additions & 19 deletions src/features/projects/data/useProjects.ts

This file was deleted.

22 changes: 22 additions & 0 deletions src/features/projects/view/ProjectsContextProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"use client"

import { useState } from "react"
import { ProjectsContext } from "@/common"
import { Project } from "@/features/projects/domain"

const ProjectsContextProvider = ({
initialProjects,
children
}: {
initialProjects?: Project[],
children?: React.ReactNode
}) => {
const [projects, setProjects] = useState<Project[]>(initialProjects || [])
return (
<ProjectsContext.Provider value={{ projects, setProjects }}>
{children}
</ProjectsContext.Provider>
)
}

export default ProjectsContextProvider
20 changes: 0 additions & 20 deletions src/features/projects/view/ServerSideCachedProjectsProvider.tsx

This file was deleted.

11 changes: 4 additions & 7 deletions src/features/sidebar/view/SecondarySplitHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use client"

import { useState, useEffect, useContext } from "react"
import { useState, useEffect } from "react"
import { useSessionStorage } from "usehooks-ts"
import { Box, IconButton, Stack, Tooltip, Divider, Collapse } from "@mui/material"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faBars, faChevronLeft } from "@fortawesome/free-solid-svg-icons"
import { useTheme } from "@mui/material/styles"
import { SidebarContext, isMac as checkIsMac } from "@/common"
import { isMac as checkIsMac } from "@/common"
import { useSidebarOpen } from "@/features/sidebar/data"
import ToggleMobileToolbarButton from "./internal/secondary/ToggleMobileToolbarButton"

Expand All @@ -23,15 +23,13 @@ const Header = ({
}) => {
const [isSidebarOpen, setSidebarOpen] = useSidebarOpen()
const [isMac, setIsMac] = useState(false)
const { isToggleable: isSidebarToggleable } = useContext(SidebarContext)
const [isMobileToolbarVisible, setMobileToolbarVisible] = useSessionStorage("isMobileToolbarVisible", true)
useEffect(() => {
// checkIsMac uses window so we delay the check.
setIsMac(checkIsMac())
}, [isMac, setIsMac])
const openCloseKeyboardShortcut = `(${isMac ? "⌘" : "^"} + .)`
const theme = useTheme()

return (
<Box
sx={{
Expand All @@ -48,7 +46,7 @@ const Header = ({
margin: "auto",
height: HEIGHT_HEADER
}}>
{isSidebarToggleable && !isSidebarOpen &&
{!isSidebarOpen &&
<Tooltip title={`Show Projects ${openCloseKeyboardShortcut}`}>
<IconButton
size="medium"
Expand All @@ -64,7 +62,7 @@ const Header = ({
</IconButton>
</Tooltip>
}
{isSidebarToggleable && isSidebarOpen &&
{isSidebarOpen &&
<Tooltip title={`Hide Projects ${openCloseKeyboardShortcut}`}>
<IconButton
size="small"
Expand Down Expand Up @@ -104,7 +102,6 @@ const Header = ({
</Collapse>
}
{showDivider && <Divider />}

</Box>
)
}
Expand Down
62 changes: 16 additions & 46 deletions src/features/sidebar/view/SplitView.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,22 @@
"use client"
import ClientSplitView from "./internal/ClientSplitView"
import { projectDataSource } from "@/composition"
import BaseSidebar from "./internal/sidebar/Sidebar"
import ProjectList from "./internal/sidebar/projects/ProjectList"

import { useEffect } from "react"
import { Stack } from "@mui/material"
import { isMac, useKeyboardShortcut } from "@/common"
import { useSidebarOpen } from "../data"
import PrimaryContainer from "./internal/primary/Container"
import SecondaryContainer from "./internal/secondary/Container"
import Sidebar from "./internal/sidebar/Sidebar"

const SplitView = ({
canToggleSidebar: _canToggleSidebar,
children
}: {
canToggleSidebar?: boolean
children?: React.ReactNode
}) => {
const [isSidebarOpen, setSidebarOpen] = useSidebarOpen()
const canToggleSidebar = _canToggleSidebar !== undefined ? _canToggleSidebar : true
useEffect(() => {
// Show the sidebar if no project is selected.
if (!canToggleSidebar) {
setSidebarOpen(true)
}
}, [canToggleSidebar, setSidebarOpen])
useKeyboardShortcut(event => {
const isActionKey = isMac() ? event.metaKey : event.ctrlKey
if (isActionKey && event.key === ".") {
event.preventDefault()
if (canToggleSidebar) {
setSidebarOpen(!isSidebarOpen)
}
}
}, [canToggleSidebar, setSidebarOpen])
const sidebarWidth = 320
const SplitView = ({ children }: { children?: React.ReactNode }) => {
return (
<Stack direction="row" spacing={0} sx={{ width: "100%", height: "100%" }}>
<PrimaryContainer
width={sidebarWidth}
isOpen={isSidebarOpen}
onClose={() => setSidebarOpen(false)}
>
<Sidebar/>
</PrimaryContainer>
<SecondaryContainer sidebarWidth={sidebarWidth} offsetContent={isSidebarOpen}>
{children}
</SecondaryContainer>
</Stack>
<ClientSplitView sidebar={<Sidebar/>}>
{children}
</ClientSplitView>
)
}

export default SplitView

const Sidebar = () => {
return (
<BaseSidebar>
<ProjectList projectDataSource={projectDataSource} />
</BaseSidebar>
)
}
Loading