mirror of
https://github.com/block/buzz.git
synced 2026-10-31 14:31:02 +00:00
fix(desktop): restore the Projects sidebar row and overview route
The channel-first migration removed the Projects row from the sidebar's
primary menu and turned /projects into a redirect to home, leaving the
projects overview (ProjectsScreen) unreachable: the sidebar Projects
section's "Browse all" action and every other goProjects() caller
silently landed on the Inbox.
Bring back the entry point without reverting the migration:
- /projects renders ProjectsScreen again (lazy, in Suspense) instead of
redirecting to /. The usePreviewFeatureWarning("projects") call from
the pre-promotion route stays gone.
- The primary menu shows Projects under Inbox again, wired through
onSelectProjects and projectsOverviewActive exactly as before, but
with no FeatureGate: Projects was promoted out of preview features on
this branch and the "projects" feature id no longer exists, so the
old gate would only re-flood the console with unknown-feature
warnings.
- channel-project-features.spec.ts pinned the row's absence; it now
asserts the row is visible alongside the sidebar Projects section.
badge.spec.ts already required the row (primary rows share the same
inactive emphasis) and passes again without changes.
Verified: desktop unit suite 5943 passing; tsc, biome clean; the
channel-project-features and badge smoke specs pass (20 tests).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
This commit is contained in:
@@ -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?.[
|
||||
|
||||
@@ -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 (
|
||||
<React.Suspense fallback={<ViewLoadingFallback kind="projects" />}>
|
||||
<ProjectsScreen />
|
||||
</React.Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ export type AppSidebarProps = {
|
||||
isCreatingChannel: boolean;
|
||||
isCreatingForum: boolean;
|
||||
profile?: Profile;
|
||||
projectsOverviewActive: boolean;
|
||||
relayConnectionCard: ReturnType<typeof useSidebarRelayConnectionCard>;
|
||||
selfPresenceStatus: PresenceStatus;
|
||||
errorMessage?: string;
|
||||
@@ -82,6 +83,7 @@ export type AppSidebarProps = {
|
||||
onRemoveCommunity: (id: string) => Promise<LeaveCommunityResult | undefined>;
|
||||
onCreateAgent: () => void;
|
||||
onSelectAgents: () => void;
|
||||
onSelectProjects: () => void;
|
||||
onSelectPulse: () => void;
|
||||
onSelectWorkflows: () => void;
|
||||
onSelectHome: () => void;
|
||||
|
||||
@@ -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({
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
</FeatureGate>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton
|
||||
data-testid="open-projects-view"
|
||||
isActive={selectedView === "projects" && projectsOverviewActive}
|
||||
onClick={onSelectProjects}
|
||||
tooltip="Projects"
|
||||
type="button"
|
||||
>
|
||||
<Folders className="h-4 w-4" />
|
||||
<SidebarMenuLabel>Projects</SidebarMenuLabel>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton
|
||||
className="data-[active=true]:font-normal"
|
||||
|
||||
@@ -278,7 +278,7 @@ test("existing channel project data infers features with separate Projects navig
|
||||
await expect
|
||||
.poll(async () => (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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user