diff --git a/desktop/src/app/AppShell.tsx b/desktop/src/app/AppShell.tsx index 48ddb8a10f..eb5ab5a95d 100644 --- a/desktop/src/app/AppShell.tsx +++ b/desktop/src/app/AppShell.tsx @@ -147,6 +147,7 @@ export function AppShell() { goChannel, goHome, goNewMessage, + goProjects, goPulse, goSettings, goWorkflows, @@ -885,6 +886,7 @@ export function AppShell() { scopeSearchFocusRequest, ]} onSelectHome={() => void goHome()} + onSelectProjects={() => void goProjects()} onSelectPulse={() => void goPulse()} onSelectSettings={handleOpenSettings} onSelectWorkflows={() => void goWorkflows()} @@ -901,6 +903,9 @@ export function AppShell() { }) } profile={profileQuery.data} + projectsOverviewActive={ + location.pathname === "/projects" + } selfUserStatus={ deferredPubkey ? (selfStatusQuery.data?.[ diff --git a/desktop/src/app/routes/projects.tsx b/desktop/src/app/routes/projects.tsx index 75871c03b4..bd6a7064a9 100644 --- a/desktop/src/app/routes/projects.tsx +++ b/desktop/src/app/routes/projects.tsx @@ -1,7 +1,21 @@ -import { createFileRoute, redirect } from "@tanstack/react-router"; +import * as React from "react"; +import { createFileRoute } from "@tanstack/react-router"; + +import { ViewLoadingFallback } from "@/shared/ui/ViewLoadingFallback"; + +const ProjectsScreen = React.lazy(async () => { + const module = await import("@/features/projects/ui/ProjectsScreen"); + return { default: module.ProjectsScreen }; +}); export const Route = createFileRoute("/projects")({ - beforeLoad: () => { - throw redirect({ to: "/" }); - }, + component: ProjectsRouteComponent, }); + +function ProjectsRouteComponent() { + return ( + }> + + + ); +} diff --git a/desktop/src/features/sidebar/ui/AppSidebar.tsx b/desktop/src/features/sidebar/ui/AppSidebar.tsx index bb68e75328..6d9a678659 100644 --- a/desktop/src/features/sidebar/ui/AppSidebar.tsx +++ b/desktop/src/features/sidebar/ui/AppSidebar.tsx @@ -91,6 +91,7 @@ export function AppSidebar({ isCreatingChannel, isCreatingForum, profile, + projectsOverviewActive, relayConnectionCard, selfPresenceStatus, errorMessage, @@ -116,6 +117,7 @@ export function AppSidebar({ onRemoveCommunity, onCreateAgent, onSelectAgents, + onSelectProjects, onSelectPulse, onSelectWorkflows, onSelectHome, @@ -542,8 +544,10 @@ export function AppSidebar({ homeBadgeCount={homeBadgeCount} onSelectAgents={onSelectAgents} onSelectHome={onSelectHome} + onSelectProjects={onSelectProjects} onSelectPulse={onSelectPulse} onSelectWorkflows={onSelectWorkflows} + projectsOverviewActive={projectsOverviewActive} selectedView={selectedView} /> diff --git a/desktop/src/features/sidebar/ui/AppSidebar.types.ts b/desktop/src/features/sidebar/ui/AppSidebar.types.ts index c5c93b7b84..ab35b8b598 100644 --- a/desktop/src/features/sidebar/ui/AppSidebar.types.ts +++ b/desktop/src/features/sidebar/ui/AppSidebar.types.ts @@ -32,6 +32,7 @@ export type AppSidebarProps = { isCreatingChannel: boolean; isCreatingForum: boolean; profile?: Profile; + projectsOverviewActive: boolean; relayConnectionCard: ReturnType; selfPresenceStatus: PresenceStatus; errorMessage?: string; @@ -82,6 +83,7 @@ export type AppSidebarProps = { onRemoveCommunity: (id: string) => Promise; onCreateAgent: () => void; onSelectAgents: () => void; + onSelectProjects: () => void; onSelectPulse: () => void; onSelectWorkflows: () => void; onSelectHome: () => void; diff --git a/desktop/src/features/sidebar/ui/AppSidebarPinnedHeader.tsx b/desktop/src/features/sidebar/ui/AppSidebarPinnedHeader.tsx index f1a76824a0..cad45ca405 100644 --- a/desktop/src/features/sidebar/ui/AppSidebarPinnedHeader.tsx +++ b/desktop/src/features/sidebar/ui/AppSidebarPinnedHeader.tsx @@ -1,4 +1,4 @@ -import { Activity, Bot, Inbox, Zap } from "lucide-react"; +import { Activity, Bot, Folders, Inbox, Zap } from "lucide-react"; import { TopbarSearch } from "@/features/search/ui/TopbarSearch"; import { FeatureGate } from "@/shared/features"; @@ -41,8 +41,10 @@ type AppSidebarPrimaryMenuProps = { homeBadgeCount: number; onSelectAgents: () => void; onSelectHome: () => void; + onSelectProjects: () => void; onSelectPulse: () => void; onSelectWorkflows: () => void; + projectsOverviewActive: boolean; selectedView: SidebarSelectedView; }; @@ -89,8 +91,10 @@ export function AppSidebarPrimaryMenu({ homeBadgeCount, onSelectAgents, onSelectHome, + onSelectProjects, onSelectPulse, onSelectWorkflows, + projectsOverviewActive, selectedView, }: AppSidebarPrimaryMenuProps) { return ( @@ -134,6 +138,18 @@ export function AppSidebarPrimaryMenu({ + + + + Projects + + (await acceptedProjectEvents(page)).length) .toBe(0); - await expect(page.getByTestId("open-projects-view")).toHaveCount(0); + await expect(page.getByTestId("open-projects-view")).toBeVisible(); const projectsSection = page.getByTestId("sidebar-projects-section"); await expect(projectsSection).toBeVisible();