feat(awards): implement the QRZ.com and Custom confirmation sources
The award editor offered five confirmation sources and Def's own doc comment named five, but confirmed() had cases for three. "qrzcom" and "custom" fell through the switch, so ticking either marked nothing as confirmed — the exact failure the GrantCodes comment in this struct warns about: a checkbox that does nothing is worse than no checkbox, because it is trusted. QRZ.com reads qrzcom_qso_download_status, not the upload one: uploading a QSO is us telling QRZ about it, which confirms nothing. Custom names a field. Rather than a checkbox per external source, the Def gains ConfirmField + ConfirmValue: any QSO field or ADIF extras key, and optionally the comma-separated values that count. That one shape covers the three cases asked for — the OpsLog card marker (APP_OPSLOG_QSL_RCVD), an arbitrary ADIF tag, and a tag stamped by an imported club list — because all three end up as a field on the QSO. An empty ConfirmValue means any non-empty content confirms: the OpsLog marker stores the date the card arrived, not a Y/N flag. A custom source naming NO field confirms nothing, deliberately — the opposite default would silently mark a whole logbook confirmed.
This commit is contained in:
@@ -38,6 +38,9 @@ export type AwardDef = {
|
||||
or_rules?: AwardOrRule[];
|
||||
dxcc_filter: number[] | null; valid_bands?: string[]; valid_modes?: string[]; emission?: string[];
|
||||
confirm: string[] | null; validate?: string[] | null; grant_codes?: string; export_credit_granted?: boolean;
|
||||
// The "custom" confirmation source: the field it reads and, optionally, the
|
||||
// value(s) that count. Empty value = any non-empty value confirms.
|
||||
confirm_field?: string; confirm_value?: string;
|
||||
total: number; builtin?: boolean; version?: number;
|
||||
};
|
||||
|
||||
@@ -622,6 +625,30 @@ export function AwardEditor({ open, onClose, onSaved }: Props) {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* "Custom" is only meaningful once it names a field, so the
|
||||
inputs appear as soon as it is ticked in either column —
|
||||
and a custom source with no field confirms nothing. */}
|
||||
{((cur.confirm ?? []).includes('custom') || (cur.validate ?? []).includes('custom')) && (
|
||||
<div className="space-y-2 border-t border-border/60 pt-3">
|
||||
<Label className="text-xs font-semibold">{t('awed.customLabel')}</Label>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[11px] text-muted-foreground">{t('awed.customField')}</Label>
|
||||
<Input className="h-8 font-mono text-xs" placeholder="APP_OPSLOG_QSL_RCVD"
|
||||
value={(cur as any).confirm_field ?? ''}
|
||||
onChange={(e) => patch({ confirm_field: e.target.value.trim().toUpperCase() } as any)} />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[11px] text-muted-foreground">{t('awed.customValue')}</Label>
|
||||
<Input className="h-8 font-mono text-xs" placeholder="Y,V"
|
||||
value={(cur as any).confirm_value ?? ''}
|
||||
onChange={(e) => patch({ confirm_value: e.target.value } as any)} />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-[11px] text-muted-foreground leading-relaxed">{t('awed.customHint')}</p>
|
||||
</div>
|
||||
)}
|
||||
{/* "Grant codes" and "export credit_granted" used to live here. No
|
||||
ADIF export has ever written CREDIT_GRANTED, so both controls
|
||||
did nothing at all. The stored values are kept (see award.Def);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -325,6 +325,8 @@ export namespace award {
|
||||
emission?: string[];
|
||||
confirm: string[];
|
||||
validate?: string[];
|
||||
confirm_field?: string;
|
||||
confirm_value?: string;
|
||||
grant_codes?: string;
|
||||
export_credit_granted?: boolean;
|
||||
total: number;
|
||||
@@ -367,6 +369,8 @@ export namespace award {
|
||||
this.emission = source["emission"];
|
||||
this.confirm = source["confirm"];
|
||||
this.validate = source["validate"];
|
||||
this.confirm_field = source["confirm_field"];
|
||||
this.confirm_value = source["confirm_value"];
|
||||
this.grant_codes = source["grant_codes"];
|
||||
this.export_credit_granted = source["export_credit_granted"];
|
||||
this.total = source["total"];
|
||||
|
||||
Reference in New Issue
Block a user