fix(distance): compute it where QSOs are made, not in a settings button
The button was the wrong shape twice over. A maintenance chore does not belong beside the options an operator actually chooses, and nobody should have to be told their log is missing a field before it gets filled in. So the distance is computed where QSOs come from: on the logging path and on the ADIF import. fillDistance is its own function rather than part of applyStationDefaults, because the import only applies those when the operator ticks a box — and a distance is not a station default. It is derived from the QSO's own two grids and is true whatever was chosen about profile fields. What is already in the log is handled by a one-time migration at startup, recorded by a settings key. In the background: on a large log over a remote MySQL that is thousands of row updates and startup must not wait for a tidy-up. Marked done only on SUCCESS, so a run cut short by a closed program tries again next time rather than leaving half the log filled for ever. An imported value still wins. It came from the log that made the contact, which knew the real positions rather than two four-character squares.
This commit is contained in:
@@ -45,7 +45,7 @@ import {
|
||||
TestLoTWUpload, ListTQSLStationLocations,
|
||||
DownloadLoTWUsers, GetLoTWUsersStatus,
|
||||
GetScpStatus, SetScpEnabled, DownloadScp,
|
||||
DownloadULSCounties, ULSStatus, BackfillUSCounties, BackfillDistances,
|
||||
DownloadULSCounties, ULSStatus, BackfillUSCounties,
|
||||
ComputeStationInfo,
|
||||
GetUIPref, SetUIPref,
|
||||
GetFlexState, GetFlexBandAntennas, SaveFlexBandAntennas, GetFlexBandPower, SaveFlexBandPower,
|
||||
@@ -1495,14 +1495,6 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
||||
try { await DownloadULSCounties(); }
|
||||
catch (e: any) { setUlsBusy(false); setUlsProgress(null); setUlsMsg({ ok: false, text: String(e?.message ?? e) }); }
|
||||
};
|
||||
const [distBusy, setDistBusy] = useState(false);
|
||||
const [distMsg, setDistMsg] = useState<string | null>(null);
|
||||
const runDistBackfill = async () => {
|
||||
setDistBusy(true); setDistMsg(null);
|
||||
try { const r: any = await BackfillDistances(); setDistMsg(t("db.distDone", { f: r?.filled ?? 0, s: r?.scanned ?? 0, n: r?.no_grid ?? 0 })); }
|
||||
catch (e: any) { setDistMsg(String(e?.message ?? e)); }
|
||||
finally { setDistBusy(false); }
|
||||
};
|
||||
const runBackfill = async () => {
|
||||
setBackfillBusy(true); setBackfillMsg(null);
|
||||
try { const r: any = await BackfillUSCounties(); setBackfillMsg(t('uscty.backfillDone', { c: r?.county ?? 0, g: r?.grid ?? 0, s: r?.scanned ?? 0 })); }
|
||||
@@ -5331,21 +5323,6 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
||||
<>
|
||||
<SectionHeader title={t('sec.database')} />
|
||||
|
||||
{/* Distance backfill. Here rather than beside the county one, which lives
|
||||
in the US Counties panel: this touches the whole logbook, whatever
|
||||
country the QSOs are in. */}
|
||||
<div className="rounded-md border border-border p-3 space-y-2 max-w-2xl mb-5">
|
||||
<div className="text-xs font-medium">{t('db.distTitle')}</div>
|
||||
<p className="text-[11px] text-muted-foreground leading-relaxed">{t('db.distIntro')}</p>
|
||||
<div className="flex items-center gap-3">
|
||||
<Button size="sm" variant="secondary" onClick={runDistBackfill} disabled={distBusy}>
|
||||
{distBusy ? <Loader2 className="size-3.5 animate-spin mr-1.5" /> : null}
|
||||
{t('db.distRun')}
|
||||
</Button>
|
||||
{distMsg && <span className="text-xs text-muted-foreground">{distMsg}</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Settings / application database (settings + profiles) — always shown,
|
||||
distinct from the QSO logbook so the two are never confused. */}
|
||||
<div className="space-y-2 max-w-2xl mb-5 border border-border/60 rounded-md p-3">
|
||||
|
||||
Reference in New Issue
Block a user