fix(antenna): pick the SteppIR's serial port from a list

The COM port was a bare text field — the only serial device in the app without
a port list, and typing one by hand gave no clue when it failed.

A Combobox rather than the Select the other devices use, deliberately: the port
of a USB adapter that is not plugged in does not appear in any list, and
refusing a typed value would mean the antenna cannot be configured until the
adapter is in. Detected ports are offered, anything else is still accepted, and
the value is trimmed and upper-cased on the way in.

The failure itself was already logged by the SteppIR client ("cannot open COM7
@ 4800 baud"); what was missing was the line above it not claiming the antenna
had connected. That is fixed separately.

Carries the 0.26.2 changelog entries for this and the three preceding commits —
one file, and splitting it four ways would have said less than this does.
This commit is contained in:
2026-08-21 14:36:07 +02:00
parent d01c288454
commit c49faf9a14
2 changed files with 40 additions and 6 deletions
+20 -6
View File
@@ -68,6 +68,7 @@ import {
import { WebPublishPanel } from '@/components/WebPublishPanel';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Combobox } from '@/components/ui/combobox';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Checkbox } from '@/components/ui/checkbox';
@@ -3458,12 +3459,25 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
<div className="grid grid-cols-3 gap-3">
<div className="space-y-1 col-span-2">
<Label>{t('hw.motorCom')}</Label>
<Input
value={ultrabeam.com ?? ''}
onChange={(e) => setUltrabeam((s) => ({ ...s, com: e.target.value }))}
placeholder="COM3"
className="font-mono"
/>
{/* A list AND a text field, which is why this is a Combobox and
not the Select the other serial devices use: the port for a
USB adapter that is currently unplugged does not appear in
the list, and refusing to accept it typed means the antenna
cannot be configured until the adapter is in. The detected
ports are offered; anything else is still accepted. */}
<div className="flex items-center gap-1">
<Combobox
value={ultrabeam.com ?? ''}
options={wkPorts}
allowFreeText
commitOnType
placeholder="COM3"
className="font-mono flex-1"
onChange={(v) => setUltrabeam((s) => ({ ...s, com: v.trim().toUpperCase() }))}
/>
<Button type="button" variant="outline" size="sm" className="shrink-0"
onClick={() => ListSerialPorts().then((ps) => setWkPorts((ps ?? []) as string[])).catch(() => {})}></Button>
</div>
</div>
<div className="space-y-1">
<Label>{t('hw.motorBaud')}</Label>