fix(dashboard): dedupe host kind in header connection pill and unify its font size
The connection status pill rendered the host kind twice ('Desktop
Desktop local mode') with mismatched font sizes. The kind is now folded
once into the summary ('Desktop · Local mode') across all pill states.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
7
.changeset/header-pill-dedupe.md
Normal file
7
.changeset/header-pill-dedupe.md
Normal file
@@ -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.
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 · <profile> · <origin>", "Mobile · <profile> · <origin>"), 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 (
|
||||
<button type="button" className="btn shell-connection-status" onClick={() => void handleClick()} data-testid="shell-connection-status-button">
|
||||
<span className={view.dotClassName} aria-hidden="true" />
|
||||
<span className="shell-connection-status__kind">{status.hostKind === "desktop-shell" ? "Desktop" : "Mobile"}</span>
|
||||
<span className="shell-connection-status__summary" title={view.title}>{view.title}</span>
|
||||
<span className="shell-connection-status__action">{view.actionLabel}</span>
|
||||
</button>
|
||||
|
||||
@@ -17,18 +17,24 @@ function makeStatus(overrides: Partial<ShellConnectionNativeResult> = {}): 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(<ShellConnectionStatus status={makeStatus({ mode: "local" })} />);
|
||||
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(<ShellConnectionStatus status={makeStatus()} />);
|
||||
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(
|
||||
<ShellConnectionStatus
|
||||
status={makeStatus({ mode: "remote", profileId: undefined, profileLabel: undefined, serverOrigin: undefined })}
|
||||
/>,
|
||||
);
|
||||
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", () => {
|
||||
|
||||
Reference in New Issue
Block a user