fix(sat,rda): the dropdown reads the live list, and the RDA buttons answer

SATELLITES: the field read the list once, when the details panel first
mounted — which is at startup. A list saved in Preferences afterwards
therefore did nothing until a restart. It comes from App now, which
already reloads the lists when Preferences close.

RDA COMPARE: a failed comparison wrote its error into the message beside
the FILL DISTRICTS button, a row above — the error appeared under a
button nobody had pressed while the one that had been pressed showed
nothing, which reads as 'the button does nothing'. It has its own message
now, and reports the two results that look like silence: no disagreement
at all, and no Russian contacts to compare. Both buttons say what they
are doing while they do it, and the comparison logs before it starts
reading — on a remote MySQL that read is seconds of quiet.
This commit is contained in:
2026-08-25 19:53:30 +02:00
parent e41a3a4c1c
commit 67c85be23c
6 changed files with 45 additions and 20 deletions
+19 -5
View File
@@ -1927,10 +1927,23 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
// operator's own log, and answering it must not modify that log.
const [rdaCmp, setRdaCmp] = useState<any>(null);
const [rdaCmpBusy, setRdaCmpBusy] = useState(false);
// Its own message, next to its own button.
//
// A failed comparison used to write into rdaMsg — which is rendered beside
// the FILL DISTRICTS button, a row above. The error appeared under a button
// nobody had pressed, and the one that had been pressed showed nothing at
// all, which reads as "the button does nothing".
const [rdaCmpMsg, setRdaCmpMsg] = useState<string>('');
const runRDACompare = async () => {
setRdaCmpBusy(true); setRdaCmp(null);
try { setRdaCmp(await CompareRDASources()); }
catch (e: any) { setRdaMsg(String(e?.message ?? e)); }
setRdaCmpBusy(true); setRdaCmp(null); setRdaCmpMsg('');
try {
const r: any = await CompareRDASources();
setRdaCmp(r);
// A comparison that finds nothing is a RESULT, and the most likely one on
// a tidy log. Without a word for it the panel looked like it had not run.
if (!r || (r.scanned ?? 0) === 0) setRdaCmpMsg(t('rda.cmpNoRussian'));
else if ((r.disagree ?? 0) === 0) setRdaCmpMsg(t('rda.cmpNoConflict'));
} catch (e: any) { setRdaCmpMsg(String(e?.message ?? e)); }
finally { setRdaCmpBusy(false); }
};
@@ -7421,7 +7434,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
<div className="flex items-center gap-3">
<Button size="sm" variant="secondary" onClick={runRDABackfill} disabled={rdaBusy}>
{rdaBusy ? <Loader2 className="size-3.5 animate-spin mr-1.5" /> : null}
{t('rda.backfillRun')}
{rdaBusy ? t('rda.backfillRunning') : t('rda.backfillRun')}
</Button>
{rdaMsg && <span className="text-xs text-muted-foreground">{rdaMsg}</span>}
</div>
@@ -7435,8 +7448,9 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
<div className="flex items-center gap-3">
<Button size="sm" variant="secondary" onClick={runRDACompare} disabled={rdaCmpBusy}>
{rdaCmpBusy ? <Loader2 className="size-3.5 animate-spin mr-1.5" /> : null}
{t('rda.cmpRun')}
{rdaCmpBusy ? t('rda.cmpRunning') : t('rda.cmpRun')}
</Button>
{!!rdaCmpMsg && <span className="text-xs text-muted-foreground">{rdaCmpMsg}</span>}
{rdaCmp && (
<span className="text-xs text-muted-foreground">
{t('rda.cmpDone', {