fix(FN-2061): remove agents tab from mobile nav
- Remove the agents tab button and showAgentsTab prop from MobileNavBar. - Stop passing showAgentsTab from App to keep mobile navigation aligned with current feature exposure. - Update MobileNavBar and mobile regression tests to remove agents-tab assertions and verify agents access via header fallback when mobile nav is disabled.
This commit is contained in:
@@ -683,7 +683,6 @@ function AppInner() {
|
||||
onOpenQuickChat={() => setQuickChatOpen(true)}
|
||||
projectId={currentProject?.id}
|
||||
showSkillsTab={skillsEnabled}
|
||||
showAgentsTab={agentsEnabled}
|
||||
experimentalFeatures={{ insights: insightsEnabled, roadmap: roadmapEnabled, memoryView: memoryEnabled }}
|
||||
/>
|
||||
{viewMode === "project" && currentProject && taskView !== "chat" && taskView !== "mailbox" && taskView !== "insights" && (
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* Protected features:
|
||||
* - List view toggle
|
||||
* - Board view toggle
|
||||
* - Agents view toggle
|
||||
* - Agents view toggle (via header fallback on mobile when mobile nav is disabled)
|
||||
* - Project overview / "All Projects" navigation
|
||||
* - Secondary features via "More" sheet (settings, git, terminal, etc.)
|
||||
*/
|
||||
@@ -111,15 +111,10 @@ describe("Mobile Feature Access Regression Guard", () => {
|
||||
expect(props.onChangeView).toHaveBeenCalledWith("list");
|
||||
});
|
||||
|
||||
it("agents view is accessible via mobile nav bar", () => {
|
||||
const props = createDefaultMobileNavProps();
|
||||
render(<MobileNavBar {...props} showAgentsTab={true} />);
|
||||
it("agents tab is not rendered in the mobile nav bar", () => {
|
||||
render(<MobileNavBar {...createDefaultMobileNavProps()} />);
|
||||
|
||||
const agentsTab = screen.getByTestId("mobile-nav-tab-agents");
|
||||
expect(agentsTab).toBeDefined();
|
||||
|
||||
fireEvent.click(agentsTab);
|
||||
expect(props.onChangeView).toHaveBeenCalledWith("agents");
|
||||
expect(screen.queryByTestId("mobile-nav-tab-agents")).toBeNull();
|
||||
});
|
||||
|
||||
it("project list is accessible via header overflow menu on mobile", () => {
|
||||
@@ -206,21 +201,20 @@ describe("Mobile Feature Access Regression Guard", () => {
|
||||
expect(screen.getByTitle("Agents view")).toBeDefined();
|
||||
});
|
||||
|
||||
it("all three task views remain reachable from mobile navigation surfaces", () => {
|
||||
it("all three task views remain reachable across mobile navigation surfaces", () => {
|
||||
const mobileNavOnChangeView = vi.fn();
|
||||
const mobileNav = render(
|
||||
<MobileNavBar
|
||||
{...createDefaultMobileNavProps()}
|
||||
view="missions"
|
||||
onChangeView={mobileNavOnChangeView}
|
||||
showAgentsTab={true}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByTestId("mobile-nav-tab-tasks"));
|
||||
fireEvent.click(screen.getByTestId("mobile-nav-tab-agents"));
|
||||
|
||||
expect(mobileNavOnChangeView).toHaveBeenCalledWith("board");
|
||||
expect(mobileNavOnChangeView).toHaveBeenCalledWith("agents");
|
||||
expect(screen.queryByTestId("mobile-nav-tab-agents")).toBeNull();
|
||||
|
||||
mobileNav.unmount();
|
||||
|
||||
@@ -230,10 +224,13 @@ describe("Mobile Feature Access Regression Guard", () => {
|
||||
view="board"
|
||||
onChangeView={headerOnChangeView}
|
||||
mobileNavEnabled={false}
|
||||
showAgentsTab={true}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByTitle("List view"));
|
||||
fireEvent.click(screen.getByTitle("Agents view"));
|
||||
expect(headerOnChangeView).toHaveBeenCalledWith("list");
|
||||
expect(headerOnChangeView).toHaveBeenCalledWith("agents");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
Activity,
|
||||
Bot,
|
||||
Brain,
|
||||
ChevronRight,
|
||||
Clock,
|
||||
@@ -59,8 +58,6 @@ export interface MobileNavBarProps {
|
||||
onViewAllProjects?: () => void;
|
||||
/** Whether to show the skills tab */
|
||||
showSkillsTab?: boolean;
|
||||
/** When true, shows the Agents mobile tab. Hidden by default (experimental feature). */
|
||||
showAgentsTab?: boolean;
|
||||
/** Experimental feature flags controlling visibility of nav items. */
|
||||
experimentalFeatures?: { insights?: boolean; roadmap?: boolean; memoryView?: boolean };
|
||||
}
|
||||
@@ -108,7 +105,6 @@ export function MobileNavBar({
|
||||
projectId,
|
||||
onViewAllProjects,
|
||||
showSkillsTab,
|
||||
showAgentsTab,
|
||||
experimentalFeatures,
|
||||
}: MobileNavBarProps) {
|
||||
const mode = useViewportMode();
|
||||
@@ -200,20 +196,6 @@ export function MobileNavBar({
|
||||
<span className="mobile-nav-tab-label">Tasks</span>
|
||||
</button>
|
||||
|
||||
{showAgentsTab && (
|
||||
<button
|
||||
type="button"
|
||||
className={`mobile-nav-tab${view === "agents" ? " mobile-nav-tab--active" : ""}`}
|
||||
data-testid="mobile-nav-tab-agents"
|
||||
role="tab"
|
||||
aria-selected={view === "agents"}
|
||||
onClick={() => onChangeView("agents")}
|
||||
>
|
||||
<Bot />
|
||||
<span className="mobile-nav-tab-label">Agents</span>
|
||||
</button>
|
||||
)}
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className={`mobile-nav-tab${view === "missions" ? " mobile-nav-tab--active" : ""}`}
|
||||
|
||||
@@ -97,9 +97,19 @@ export function SkillsView({ projectId, addToast, onClose }: SkillsViewProps) {
|
||||
|
||||
debounceRef.current = setTimeout(() => {
|
||||
setDebouncedQuery(value);
|
||||
debounceRef.current = null;
|
||||
}, 300);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (debounceRef.current) {
|
||||
clearTimeout(debounceRef.current);
|
||||
debounceRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Fetch catalog when debounced query changes
|
||||
useEffect(() => {
|
||||
void loadCatalog(debouncedQuery);
|
||||
|
||||
@@ -56,7 +56,7 @@ describe("MobileNavBar", () => {
|
||||
mockViewport("mobile");
|
||||
});
|
||||
|
||||
it("renders six tab buttons (tasks + missions + chat + mailbox + skills + more) when showSkillsTab is true and agents is hidden by default", () => {
|
||||
it("renders six tab buttons (tasks + missions + chat + mailbox + skills + more) when showSkillsTab is true", () => {
|
||||
render(<MobileNavBar {...createDefaultProps()} showSkillsTab={true} />);
|
||||
|
||||
expect(screen.getByTestId("mobile-nav-tab-tasks")).toBeDefined();
|
||||
@@ -69,19 +69,6 @@ describe("MobileNavBar", () => {
|
||||
expect(screen.getByTestId("mobile-nav-tab-more")).toBeDefined();
|
||||
});
|
||||
|
||||
it("renders seven tab buttons when showSkillsTab and showAgentsTab are both true", () => {
|
||||
render(<MobileNavBar {...createDefaultProps()} showSkillsTab={true} showAgentsTab={true} />);
|
||||
|
||||
expect(screen.getByTestId("mobile-nav-tab-tasks")).toBeDefined();
|
||||
expect(screen.getByTestId("mobile-nav-tab-agents")).toBeDefined();
|
||||
expect(screen.getByTestId("mobile-nav-tab-missions")).toBeDefined();
|
||||
expect(screen.getByTestId("mobile-nav-tab-chat")).toBeDefined();
|
||||
expect(screen.getByTestId("mobile-nav-tab-mailbox")).toBeDefined();
|
||||
expect(screen.getByTestId("mobile-nav-tab-skills")).toBeDefined();
|
||||
expect(screen.queryByTestId("mobile-nav-tab-roadmaps")).toBeNull();
|
||||
expect(screen.getByTestId("mobile-nav-tab-more")).toBeDefined();
|
||||
});
|
||||
|
||||
it("renders roadmaps tab when experimentalFeatures.roadmap is true", () => {
|
||||
render(<MobileNavBar {...createDefaultProps()} experimentalFeatures={{ roadmap: true }} />);
|
||||
expect(screen.getByTestId("mobile-nav-tab-roadmaps")).toBeDefined();
|
||||
@@ -116,15 +103,9 @@ describe("MobileNavBar", () => {
|
||||
expect(badge?.textContent).toBe("5");
|
||||
});
|
||||
|
||||
it("active tab is highlighted for agents", () => {
|
||||
render(<MobileNavBar {...createDefaultProps()} view="agents" showAgentsTab={true} />);
|
||||
|
||||
expect(screen.getByTestId("mobile-nav-tab-agents").className).toContain("mobile-nav-tab--active");
|
||||
});
|
||||
|
||||
it("tasks tab calls onChangeView with 'board' when coming from a non-tasks view", () => {
|
||||
const props = createDefaultProps();
|
||||
render(<MobileNavBar {...props} view="agents" showAgentsTab={true} />);
|
||||
render(<MobileNavBar {...props} view="missions" />);
|
||||
|
||||
fireEvent.click(screen.getByTestId("mobile-nav-tab-tasks"));
|
||||
expect(props.onChangeView).toHaveBeenCalledWith("board");
|
||||
@@ -156,11 +137,6 @@ describe("MobileNavBar", () => {
|
||||
expect(screen.getByTestId("mobile-nav-tab-tasks").className).toContain("mobile-nav-tab--active");
|
||||
});
|
||||
|
||||
it("tasks tab is not active when view is 'agents'", () => {
|
||||
render(<MobileNavBar {...createDefaultProps()} view="agents" showAgentsTab={true} />);
|
||||
expect(screen.getByTestId("mobile-nav-tab-tasks").className).not.toContain("mobile-nav-tab--active");
|
||||
});
|
||||
|
||||
it("missions tab calls onChangeView with 'missions'", () => {
|
||||
const props = createDefaultProps();
|
||||
render(<MobileNavBar {...props} view="board" />);
|
||||
@@ -335,34 +311,11 @@ describe("MobileNavBar", () => {
|
||||
expect(container.querySelector(".mobile-nav-bar")).toBeNull();
|
||||
});
|
||||
|
||||
it("tab click calls onChangeView", () => {
|
||||
const props = createDefaultProps();
|
||||
render(<MobileNavBar {...props} showAgentsTab={true} />);
|
||||
|
||||
fireEvent.click(screen.getByTestId("mobile-nav-tab-agents"));
|
||||
expect(props.onChangeView).toHaveBeenCalledWith("agents");
|
||||
});
|
||||
|
||||
it("applies footer-visible class when footer is shown", () => {
|
||||
const { container } = render(<MobileNavBar {...createDefaultProps()} footerVisible={true} />);
|
||||
expect(container.querySelector(".mobile-nav-bar--with-footer")).not.toBeNull();
|
||||
});
|
||||
|
||||
it("hides agents tab when showAgentsTab is false", () => {
|
||||
render(<MobileNavBar {...createDefaultProps()} showAgentsTab={false} />);
|
||||
expect(screen.queryByTestId("mobile-nav-tab-agents")).toBeNull();
|
||||
});
|
||||
|
||||
it("hides agents tab by default when showAgentsTab is not provided", () => {
|
||||
render(<MobileNavBar {...createDefaultProps()} />);
|
||||
expect(screen.queryByTestId("mobile-nav-tab-agents")).toBeNull();
|
||||
});
|
||||
|
||||
it("shows agents tab when showAgentsTab is true", () => {
|
||||
render(<MobileNavBar {...createDefaultProps()} showAgentsTab={true} />);
|
||||
expect(screen.getByTestId("mobile-nav-tab-agents")).toBeDefined();
|
||||
});
|
||||
|
||||
it("returns null on desktop viewport", () => {
|
||||
mockViewport("desktop");
|
||||
const { container } = render(<MobileNavBar {...createDefaultProps()} />);
|
||||
|
||||
Reference in New Issue
Block a user