diff --git a/.changeset/header-pill-dedupe.md b/.changeset/header-pill-dedupe.md new file mode 100644 index 0000000000..bb46240593 --- /dev/null +++ b/.changeset/header-pill-dedupe.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Fix header connection pill showing "Desktop Desktop" and mixed font sizes. +category: fix +dev: ShellConnectionStatus now folds the host kind into one summary string; removed the separate __kind span and its CSS. diff --git a/packages/dashboard/app/components/ShellConnectionStatus.css b/packages/dashboard/app/components/ShellConnectionStatus.css index 8a10fd9c1b..21612b68c8 100644 --- a/packages/dashboard/app/components/ShellConnectionStatus.css +++ b/packages/dashboard/app/components/ShellConnectionStatus.css @@ -4,11 +4,11 @@ gap: var(--space-sm); } -.shell-connection-status__kind { - color: var(--text-muted); - font-size: calc(var(--space-sm) + var(--space-xs)); -} - +/* +FNXC:ShellConnectionStatusPill 2026-07-10-14:22: +The pill previously mixed a tiny host-kind label with a larger summary; the separate __kind span was removed and all pill text now shares one font size. +Summary and action intentionally have no font-size overrides so they inherit the same size; the action is distinguished by color only. +*/ .shell-connection-status__summary { color: var(--text); max-width: calc(var(--space-2xl) * 8); @@ -19,7 +19,6 @@ .shell-connection-status__action { color: var(--color-info); - font-size: calc(var(--space-sm) + var(--space-xs)); } @media (max-width: 768px) { diff --git a/packages/dashboard/app/components/ShellConnectionStatus.tsx b/packages/dashboard/app/components/ShellConnectionStatus.tsx index c2eb375316..52a1918360 100644 --- a/packages/dashboard/app/components/ShellConnectionStatus.tsx +++ b/packages/dashboard/app/components/ShellConnectionStatus.tsx @@ -7,25 +7,34 @@ export interface ShellConnectionStatusProps { onError?: (message: string) => void; } +/* +FNXC:ShellConnectionStatusPill 2026-07-10-14:20: +First-run review flagged the header pill rendering "Desktop Desktop local mode Switch server" — the host-kind word appeared twice (once as a tiny label, once inside the larger summary) with mismatched font sizes. +Requirement: the pill must render the host kind exactly once, as a single uniform-size summary ("Desktop · Local mode", "Desktop · · ", "Mobile · · "), keep the connection dot and the action label ("Switch server" / "Manage connections"), and never mix tiny and large text inside the pill. +The host kind is folded into the summary string here instead of a separate styled span; all states (local, remote, missing connection info) go through the same prefixing so no state can duplicate the word. +*/ function buildSummary(status: ShellConnectionNativeResult): { title: string; actionLabel: string; dotClassName: string } { + const kindText = status.hostKind === "desktop-shell" ? "Desktop" : "Mobile"; + if (status.hostKind === "desktop-shell" && status.mode === "local") { - return { title: "Desktop local mode", actionLabel: "Switch server", dotClassName: "status-dot status-dot--online" }; + return { title: `${kindText} · Local mode`, actionLabel: "Switch server", dotClassName: "status-dot status-dot--online" }; } const profileText = status.profileLabel ?? status.profileId; const originText = status.serverOrigin; const summary = profileText && originText ? `${profileText} · ${originText}` : profileText ?? originText; + const title = summary ? `${kindText} · ${summary}` : `${kindText} · Connection info unavailable`; if (status.mode === "remote") { return { - title: summary ?? "Connection info unavailable", + title, actionLabel: status.hostKind === "desktop-shell" ? "Switch server" : "Manage connections", dotClassName: summary ? "status-dot status-dot--online" : "status-dot status-dot--pending", }; } return { - title: summary ?? "Connection info unavailable", + title, actionLabel: "Manage connections", dotClassName: summary ? "status-dot status-dot--online" : "status-dot status-dot--pending", }; @@ -47,7 +56,6 @@ export function ShellConnectionStatus({ status, onError }: ShellConnectionStatus return ( diff --git a/packages/dashboard/app/components/__tests__/ShellConnectionStatus.test.tsx b/packages/dashboard/app/components/__tests__/ShellConnectionStatus.test.tsx index e08a5879af..473f833ced 100644 --- a/packages/dashboard/app/components/__tests__/ShellConnectionStatus.test.tsx +++ b/packages/dashboard/app/components/__tests__/ShellConnectionStatus.test.tsx @@ -17,18 +17,24 @@ function makeStatus(overrides: Partial = {}): Shell } describe("ShellConnectionStatus", () => { - it("renders local desktop mode", () => { + // FNXC:ShellConnectionStatusPill 2026-07-10-14:25: + // The header pill must render the host kind exactly once ("Desktop · Local mode"), never the old duplicated "Desktop Desktop local mode". + it("renders local desktop mode without duplicating the host kind", () => { render(); - expect(screen.getByText("Desktop local mode")).toBeInTheDocument(); + expect(screen.getByText("Desktop · Local mode")).toBeInTheDocument(); expect(screen.getByText("Switch server")).toBeInTheDocument(); + expect(screen.queryByText("Desktop local mode")).toBeNull(); + const button = screen.getByTestId("shell-connection-status-button"); + expect((button.textContent?.match(/Desktop/g) ?? []).length).toBe(1); }); it("renders remote desktop mode summary", () => { render(); - expect(screen.getByText("Desktop")).toBeInTheDocument(); - expect(screen.getByText("Prod · https://fusion.example.com")).toBeInTheDocument(); + expect(screen.getByText("Desktop · Prod · https://fusion.example.com")).toBeInTheDocument(); expect(screen.getByText("Switch server")).toBeInTheDocument(); expect(screen.getByTestId("shell-connection-status-button")).toHaveAttribute("type", "button"); + const button = screen.getByTestId("shell-connection-status-button"); + expect((button.textContent?.match(/Desktop/g) ?? []).length).toBe(1); }); it("renders remote mobile mode summary", () => { @@ -37,9 +43,21 @@ describe("ShellConnectionStatus", () => { status={makeStatus({ hostKind: "mobile-shell", mode: "remote", profileLabel: "Tablet", serverOrigin: "https://remote.example.com" })} />, ); - expect(screen.getByText("Mobile")).toBeInTheDocument(); - expect(screen.getByText("Tablet · https://remote.example.com")).toBeInTheDocument(); + expect(screen.getByText("Mobile · Tablet · https://remote.example.com")).toBeInTheDocument(); expect(screen.getByText("Manage connections")).toBeInTheDocument(); + const button = screen.getByTestId("shell-connection-status-button"); + expect((button.textContent?.match(/Mobile/g) ?? []).length).toBe(1); + }); + + it("renders unavailable connection info with a single host-kind mention", () => { + render( + , + ); + expect(screen.getByText("Desktop · Connection info unavailable")).toBeInTheDocument(); + const button = screen.getByTestId("shell-connection-status-button"); + expect((button.textContent?.match(/Desktop/g) ?? []).length).toBe(1); }); it("hides in browser/unsupported mode", () => {