diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 150eebb..4694dc5 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -4397,11 +4397,16 @@ export default function App() { onClose={() => setShowSpotModal(false)} // Callsign: the QSO-entry call, else the last logged QSO. defaultCall={callsign.trim() || qsos[0]?.callsign || ''} - // Freq: the entry TX freq (kHz), else the last logged QSO's. + // Freq (0.1 kHz): the LIVE CAT frequency in Hz when connected — NOT the + // freqMhz display string, which the manual-edit freeze / field locks can + // leave stale (that dropped the sub-kHz: on 14134.5 the frozen "14.134" + // string spotted 14134). Fall back to the entry field, then the last QSO. defaultFreqKHz={ - parseFloat(freqMhz) > 0 - ? Math.round(parseFloat(freqMhz) * 1000 * 10) / 10 - : (qsos[0]?.freq_hz ? Math.round((qsos[0].freq_hz / 1000) * 10) / 10 : 0) + catState.connected && (catState.freq_hz ?? 0) > 0 + ? Math.round(((catState.freq_hz ?? 0) / 1000) * 10) / 10 + : parseFloat(freqMhz) > 0 + ? Math.round(parseFloat(freqMhz) * 1000 * 10) / 10 + : (qsos[0]?.freq_hz ? Math.round((qsos[0].freq_hz / 1000) * 10) / 10 : 0) } defaultMode={mode || qsos[0]?.mode || ''} targetName={ diff --git a/frontend/src/components/FilterBuilder.tsx b/frontend/src/components/FilterBuilder.tsx index fdc40c5..71effcf 100644 --- a/frontend/src/components/FilterBuilder.tsx +++ b/frontend/src/components/FilterBuilder.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { Plus, Trash2, Save, FolderOpen, X } from 'lucide-react'; import { writeUiPref } from '@/lib/uiPref'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'; @@ -134,6 +134,12 @@ interface Props { export function FilterBuilder({ open, initial, onApply, onClose }: Props) { const { t } = useI18n(); + // Field dropdown sorted alphabetically by translated label (the FIELDS array is + // grouped by category for maintenance; the operator wants it A→Z to find things). + const sortedFields = useMemo( + () => FIELDS.map((f) => ({ f, txt: t(f.label) })).sort((a, b) => a.txt.localeCompare(b.txt)), + [t], + ); const [conditions, setConditions] = useState([]); const [match, setMatch] = useState<'AND' | 'OR'>('AND'); const [presets, setPresets] = useState>({}); @@ -237,7 +243,7 @@ export function FilterBuilder({ open, initial, onApply, onClose }: Props) { }}> - {FIELDS.map((f) => {t(f.label)})} + {sortedFields.map(({ f, txt }) => {txt})}