fix(entity): show the QSO's own entity, and date the ClubLog exception
Two faults behind one screenshot: 3Y0K, recorded in the log as Bouvet Island, showing the Antarctica matrix. SELECTING A QSO now shows what that QSO records. The panel asked WorkedBefore with no DXCC hint, and a hint of zero makes the backend resolve the entity from cty.dat and the ClubLog exceptions AS THEY ARE TODAY — right for a live contact, wrong for one being looked at in the log. The repo's own "infer from past QSOs" path never ran, because the hint was no longer zero by the time it got there. Hence Antarctica, and "5 QSOs with this entity" against "11 with this call": two different entities, one of them nobody had asked about. The selected row's dxcc now travels with it and is passed as the hint. Browsing the log shows what the log says, even where the log is wrong. Correcting an entity stays a deliberate act — right-click, Update from ClubLog. BACK-ENTERING A QSO now resolves the exception at the CONTACT'S date. An exception carries a validity window and a DXpedition's window closes: 3Y0K typed months later, with the activation's own date in the form, was resolved against today, matched nothing, and fell back to cty.dat. Both callers pass the date they already hold — the entry strip's, and in the editor the record's own. The date is trusted to move the resolution BACKWARDS only. A half-typed "2026-0" must not send the lookup to the year 20, and a mistyped future date must not resolve against a window that has not opened; both fall back to now. Midday rather than midnight, because a window given in whole days is inclusive of its end date and 00:00 sits exactly on the boundary.
This commit is contained in:
+24
-5
@@ -1780,7 +1780,10 @@ export default function App() {
|
||||
// Stats (F1) matrix whenever the entry form is empty — clicking a past contact
|
||||
// is the natural way to ask "what else have I got with this one?", and until
|
||||
// now the panel just sat blank.
|
||||
const [selQso, setSelQso] = useState<{ call: string; band: string; mode: string } | null>(null);
|
||||
// The selected row's own entity travels with it. Re-deriving it from the
|
||||
// callsign is what showed Antarctica for a 3Y0K contact the log records as
|
||||
// Bouvet Island — see the WorkedBefore call below.
|
||||
const [selQso, setSelQso] = useState<{ call: string; band: string; mode: string; dxcc: number } | null>(null);
|
||||
const [bulkEditIds, setBulkEditIds] = useState<number[]>([]);
|
||||
const [bulkEditOpen, setBulkEditOpen] = useState(false);
|
||||
const [showSettings, setShowSettings] = useState(false);
|
||||
@@ -3752,7 +3755,19 @@ export default function App() {
|
||||
if (!call || callsign.trim()) { setSelWb(null); return; }
|
||||
let dead = false;
|
||||
setSelWbBusy(true);
|
||||
WorkedBefore(call, 0)
|
||||
// The SELECTED QSO's own entity, not one re-derived from its callsign.
|
||||
//
|
||||
// Passing 0 lets the backend resolve the entity from cty.dat and the
|
||||
// ClubLog exceptions AS THEY ARE TODAY, which is right for a live contact
|
||||
// and wrong for one being looked at in the log. A 3Y0K contact recorded as
|
||||
// Bouvet Island showed the Antarctica matrix, and counted five contacts
|
||||
// "with this entity" against eleven with the call — two different entities,
|
||||
// one of them nobody asked about.
|
||||
//
|
||||
// Browsing the log shows what the log says, even where the log is wrong.
|
||||
// Correcting an entity is a deliberate act (right-click → Update from
|
||||
// ClubLog), not something a panel does behind the operator's back.
|
||||
WorkedBefore(call, selQso?.dxcc || 0)
|
||||
.then((w: any) => { if (!dead) setSelWb(w); })
|
||||
.catch(() => { if (!dead) setSelWb(null); })
|
||||
.finally(() => { if (!dead) setSelWbBusy(false); });
|
||||
@@ -3861,7 +3876,11 @@ export default function App() {
|
||||
const gen = lookupGenRef.current; // invalidated by ESC / resetEntry
|
||||
setLookupBusy(true);
|
||||
try {
|
||||
const r = await LookupCallsign(call);
|
||||
// The ENTRY'S date, so a ClubLog exception resolves at the moment the
|
||||
// contact happened. Live, that is now and nothing changes; back-entering
|
||||
// a past QSO, it is what makes 3Y0K come back Bouvet Island instead of
|
||||
// Antarctica — the exception's window had closed by today.
|
||||
const r = await LookupCallsign(call, qsoStartedAt ? qsoStartedAt.toISOString().slice(0, 10) : '');
|
||||
// Discard a STALE result: the operator already moved to another call
|
||||
// (clicked a new spot / typed) OR cleared the entry (ESC) while this lookup
|
||||
// was in flight. Applying it would clobber the current fields and zoom the
|
||||
@@ -5359,7 +5378,7 @@ export default function App() {
|
||||
onExportFiltered={exportFilteredADIF}
|
||||
onDelete={(ids) => setDeletingIds(ids)}
|
||||
onRowSelected={(ids) => { setSelectedIds(ids); setSelectedId(ids[0] ?? null); }}
|
||||
onRowSelectedQso={(r) => setSelQso(r ? { call: String(r.callsign ?? ""), band: String(r.band ?? ""), mode: String(r.mode ?? "") } : null)}
|
||||
onRowSelectedQso={(r) => setSelQso(r ? { call: String(r.callsign ?? ""), band: String(r.band ?? ""), mode: String(r.mode ?? ""), dxcc: Number(r.dxcc ?? 0) } : null)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -6677,7 +6696,7 @@ export default function App() {
|
||||
onExportCabrilloFiltered={exportFilteredCabrillo}
|
||||
onDelete={(ids) => setDeletingIds(ids)}
|
||||
onRowSelected={(ids) => { setSelectedIds(ids); setSelectedId(ids[0] ?? null); }}
|
||||
onRowSelectedQso={(r) => setSelQso(r ? { call: String(r.callsign ?? ""), band: String(r.band ?? ""), mode: String(r.mode ?? "") } : null)}
|
||||
onRowSelectedQso={(r) => setSelQso(r ? { call: String(r.callsign ?? ""), band: String(r.band ?? ""), mode: String(r.mode ?? ""), dxcc: Number(r.dxcc ?? 0) } : null)}
|
||||
/>
|
||||
<div className="px-3 py-1.5 border-t border-border/60 text-[11px] text-muted-foreground flex items-center justify-between gap-3 bg-muted/30">
|
||||
<div className="flex items-center gap-3">
|
||||
|
||||
@@ -374,7 +374,10 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose, countries = [], b
|
||||
// refreshes it. A cached answer from a thinner QRZ subscription (or any
|
||||
// stale row) otherwise stayed for its whole 30-day life and the button
|
||||
// appeared to do nothing.
|
||||
const r: any = await LookupCallsignFresh(call);
|
||||
// The QSO's OWN date: a ClubLog exception is resolved as of when the
|
||||
// contact happened, not as of today. Re-looking-up a DXpedition contact
|
||||
// months later must not move it to whatever the prefix means now.
|
||||
const r: any = await LookupCallsignFresh(call, (dateOn || '').slice(0, 10));
|
||||
// The lookup WINS over what is in the record — that is the point of asking
|
||||
// for it. But an EMPTY result must never blank a good value: `??` only
|
||||
// guards against null, and Go marshals an unset string as "", so a QRZ
|
||||
|
||||
Reference in New Issue
Block a user