diff --git a/src/app/features/hud/hud-dock.component.spec.ts b/src/app/features/hud/hud-dock.component.spec.ts index df35861..755bf9c 100644 --- a/src/app/features/hud/hud-dock.component.spec.ts +++ b/src/app/features/hud/hud-dock.component.spec.ts @@ -281,6 +281,21 @@ describe('HudDockComponent', () => { type('from', ''); expect(plot().disabled).toBe(false); + + // A space is not text that names a star: the field looks empty, the scene offers nothing to + // choose for it, and the button going dead would have nothing on screen to explain it. + type('from', ' '); + expect(plot().disabled).toBe(false); + + // The offer beside a refusal is the same request by another route, so it is held to the same + // test: moving the range with nothing to plot leaves the panel contradicting itself. + fixture.componentRef.setInput('routeResult', { stars: [], totalPc: 0, neededRangePc: 1.8, gaveUp: false }); + fixture.detectChanges(); + const offer = () => host().querySelector('[data-testid="route-summary"] button')!; + expect(offer().disabled).toBe(false); + + type('from', 'Sol'); + expect(offer().disabled).toBe(true); }); it('does not replay the acquire wipe over the Routes panel, whose entries survive the trip', () => { diff --git a/src/app/features/hud/routes-panel.component.ts b/src/app/features/hud/routes-panel.component.ts index be8a612..a234c1d 100644 --- a/src/app/features/hud/routes-panel.component.ts +++ b/src/app/features/hud/routes-panel.component.ts @@ -117,8 +117,9 @@ type Field = 'from' | 'to'; @if (plotted.neededRangePc !== null) { @@ -181,7 +182,9 @@ export class RoutesPanelComponent { * while the field is empty. Text left in it that names no chosen star used to fall back all the * same, so the panel read "Sol" and the route left from whatever the view had since flown to. */ - private readonly departure = computed(() => this.chosen().from ?? (this.typed().from ? null : this.currentStar())); + // Trimmed, as the scene trims the same text before offering matches for it: a field holding one + // space looks empty, offers nothing to choose, and would otherwise count as a departure. + private readonly departure = computed(() => this.chosen().from ?? (this.typed().from.trim() ? null : this.currentStar())); readonly canPlot = computed(() => this.departure() !== null && this.chosen().to !== null); readonly rangeLabel = computed(() => formatParsecs(this.rangePc()));