feat(FN-3915): move mission manager CTA to sidebar footer on desktop

Refactored the MissionManager CTA for desktop by moving it to the sidebar footer and aligning its sizing contract, with corresponding test updates and docs refresh.

Fusion-Task-Id: FN-3915
This commit is contained in:
Fusion
2026-05-10 00:07:23 -07:00
committed by gsxdsm
parent 72c50ae747
commit 0a48ed8063
5 changed files with 35 additions and 18 deletions

View File

@@ -204,20 +204,22 @@
box-shadow: var(--focus-ring-strong);
}
/* Desktop split-only sidebar header layout for mission quick actions. */
.mission-manager__sidebar-header {
/* Desktop split-only sidebar footer action bar for mission creation CTA. */
.mission-manager__sidebar-footer {
display: flex;
align-items: center;
justify-content: center;
gap: var(--space-sm);
padding: var(--space-md);
border-bottom: var(--btn-border-width) solid var(--border);
border-top: var(--btn-border-width) solid var(--border);
}
.mission-manager__sidebar-cta {
width: 100%;
min-height: calc(var(--space-lg) * 2 + var(--space-xs));
justify-content: center;
gap: var(--space-sm);
font-size: inherit;
}
/* Hide duplicate sidebar title; the shared header already labels this view. */

View File

@@ -3912,17 +3912,6 @@ export function MissionManager({ isOpen, isInline = false, onClose, addToast, pr
aria-label="Mission list"
style={isMobile ? undefined : { width: `${sidebarWidth}px` }}
>
<div className="mission-manager__sidebar-header">
<button
className="btn btn-sm btn-primary mission-manager__sidebar-cta"
onClick={() => setShowInterviewModal(true)}
title="Plan New Mission"
aria-label="Plan New Mission"
>
<Sparkles size={14} />
Plan New Mission
</button>
</div>
<div className="mission-manager__sidebar-list">
{loading ? (
<div className="mission-manager__loading">
@@ -3933,6 +3922,17 @@ export function MissionManager({ isOpen, isInline = false, onClose, addToast, pr
renderMissionListContent({ hideBottomButtons: true })
)}
</div>
<div className="mission-manager__sidebar-footer" data-testid="mission-sidebar-footer">
<button
className="btn btn-primary mission-manager__sidebar-cta"
onClick={() => setShowInterviewModal(true)}
title="Plan New Mission"
aria-label="Plan New Mission"
>
<Sparkles size={14} />
Plan New Mission
</button>
</div>
</aside>
{!isMobile && (

View File

@@ -135,6 +135,18 @@ describe("desktop two-panel split CSS", () => {
expect(css).toContain("overflow-y: auto;");
});
it("anchors desktop Plan New Mission CTA in a sidebar footer with tokenized height", () => {
const css = loadAllAppCss();
const footerRule = css.match(/\.mission-manager__sidebar-footer\s*\{[^}]*\}/)?.[0];
expect(footerRule).toContain("border-top: var(--btn-border-width) solid var(--border);");
const ctaRule = css.match(/\.mission-manager__sidebar-cta\s*\{[^}]*\}/)?.[0];
expect(ctaRule).toContain("width: 100%;");
expect(ctaRule).toContain("min-height: calc(var(--space-lg) * 2 + var(--space-xs));");
expect(ctaRule).toContain("justify-content: center;");
});
it("defines split container as flex row", () => {
const css = loadAllAppCss();
expect(css).toContain(".mission-manager__split {");

View File

@@ -775,14 +775,17 @@ describe("MissionManager", () => {
expect(mobileSpan?.textContent).toBe("Build Auth System");
});
it("sidebar header surfaces a centered Plan New Mission CTA", async () => {
it("renders the desktop Plan New Mission CTA in the sidebar footer action region", async () => {
globalThis.fetch = createFetchMock();
render(<MissionManager isOpen={true} onClose={vi.fn()} addToast={vi.fn()} />);
await waitFor(() => {
const cta = document.querySelector(".mission-manager__sidebar-cta");
const sidebar = screen.getByTestId("mission-sidebar");
const sidebarFooter = within(sidebar).getByTestId("mission-sidebar-footer");
const cta = within(sidebarFooter).getByRole("button", { name: "Plan New Mission" });
expect(cta).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Plan New Mission" })).toBeInTheDocument();
expect(within(sidebar).queryByText("No missions yet")).toBeNull();
});
});
});