style(qsl): paper and LoTW first, then alphabetical
The channel list had grown in the order channels were added, so finding one meant remembering when it arrived. Paper QSL and LoTW lead — they are the two that carry an ARRL award — and the rest sort by name. One ordering function feeds both the picker and the status table, so the two cannot drift apart; the three extras-backed channels (OpsLog card, HAMLOG.online, HamQTH) now sit in that same list instead of being appended by hand after it.
This commit is contained in:
+4
-2
@@ -11,7 +11,8 @@
|
||||
"Confirmations: a HamQTH row — sent only, defaulting to R (to upload), since HamQTH publishes no confirmations to receive. Setting such a default no longer disables the auto-upload it was meant to arm (it also affected HAMLOG.online).",
|
||||
"New DXpeditions tab (Tools): the announced operations from NG3K’s ADXO next to the DX-World news feed. Every announcement is judged against YOUR log and carries one badge — NEW DXCC, NEW BAND, NEW SLOT… — with an “only what I need” filter, and one click adds its callsigns to the watchlist. The news headlines carry the same Watch button, over the callsigns mined out of their titles.",
|
||||
"Watchlist: adding or removing a callsign now raises the same kind of notification as a new version, instead of a message inside the watchlist page — a call can be added from the cluster or the DXpeditions tab, where that message was never seen.",
|
||||
"QSO editor, QSL Info: a HamQTH channel and its row in the status table — sent only, the received column showing a dash since the site publishes no confirmations."
|
||||
"QSO editor, QSL Info: a HamQTH channel and its row in the status table — sent only, the received column showing a dash since the site publishes no confirmations.",
|
||||
"QSO editor, QSL Info: the confirmation channels are listed paper QSL and LoTW first — the two that carry an ARRL award — then alphabetically, in both the picker and the status table."
|
||||
],
|
||||
"fr": [
|
||||
"Changer de base de réglages n’affiche plus « OpsLog is already running » : la relance automatique attend désormais que l’instance qui se ferme libère son verrou au lieu de la prendre de vitesse.",
|
||||
@@ -22,7 +23,8 @@
|
||||
"Confirmations : une ligne HamQTH — envoi seulement, à R (à envoyer) par défaut, HamQTH ne publiant aucune confirmation à recevoir. Définir un tel défaut ne désactive plus l’upload automatique qu’il était censé armer (cela touchait aussi HAMLOG.online).",
|
||||
"Nouvel onglet DXpéditions (Outils) : les opérations annoncées par l’ADXO de NG3K à côté du fil d’actualités DX-World. Chaque annonce est jugée sur VOTRE log et porte un badge — NOUVEAU DXCC, NOUVELLE BANDE, NOUVEAU SLOT… — avec un filtre « seulement ce qu’il me manque », et un clic ajoute ses indicatifs à la watchlist. Les actualités portent le même bouton Surveiller, sur les indicatifs extraits de leurs titres.",
|
||||
"Watchlist : ajouter ou retirer un indicatif déclenche désormais une notification du même type que celle des nouvelles versions, au lieu d’un message dans la page watchlist — un indicatif peut être ajouté depuis le cluster ou l’onglet DXpéditions, où ce message n’était jamais vu.",
|
||||
"Éditeur de QSO, onglet QSL : un canal HamQTH et sa ligne dans le tableau des statuts — envoi seulement, la colonne reçu affichant un tiret puisque le site ne publie aucune confirmation."
|
||||
"Éditeur de QSO, onglet QSL : un canal HamQTH et sa ligne dans le tableau des statuts — envoi seulement, la colonne reçu affichant un tiret puisque le site ne publie aucune confirmation.",
|
||||
"Éditeur de QSO, onglet QSL : les canaux de confirmation sont classés QSL papier puis LoTW — les deux qui comptent pour un diplôme ARRL — puis par ordre alphabétique, dans le sélecteur comme dans le tableau."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -80,6 +80,19 @@ const CONF_LABEL_KEYS: Record<string, string> = {
|
||||
QSL: 'qedit.confQslPaper',
|
||||
};
|
||||
|
||||
// Reading order for the channel list: the two that carry an ARRL award first —
|
||||
// paper QSL and LoTW — then everything else alphabetically, so a channel is
|
||||
// found by its name rather than by remembering the order it was added in.
|
||||
const CONF_FIRST: Record<string, number> = { QSL: 0, LOTW: 1 };
|
||||
function confOrder<T extends { key: string; label: string }>(rows: T[]): T[] {
|
||||
return rows.slice().sort((a, b) => {
|
||||
const ra = CONF_FIRST[a.key] ?? 2;
|
||||
const rb = CONF_FIRST[b.key] ?? 2;
|
||||
if (ra !== rb) return ra - rb;
|
||||
return a.label.localeCompare(b.label);
|
||||
});
|
||||
}
|
||||
|
||||
// OpsLog's own card. Kept out of CONFIRMATIONS on purpose — that list maps QSO
|
||||
// columns and this channel is backed by ADIF extras — but it still belongs in
|
||||
// the channel picker and the status table alongside the rest.
|
||||
@@ -756,15 +769,19 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose, countries = [], b
|
||||
<Select value={confSel} onValueChange={setConfSel}>
|
||||
<SelectTrigger><SelectValue /></SelectTrigger>
|
||||
<SelectContent>
|
||||
{CONFIRMATIONS.map((c) => <SelectItem key={c.key} value={c.key}>{CONF_LABEL_KEYS[c.key] ? t(CONF_LABEL_KEYS[c.key]) : c.label}</SelectItem>)}
|
||||
{/* Listed here but NOT in CONFIRMATIONS: that table maps
|
||||
{confOrder([
|
||||
...CONFIRMATIONS.map((c) => ({ key: c.key, label: CONF_LABEL_KEYS[c.key] ? t(CONF_LABEL_KEYS[c.key]) : c.label })),
|
||||
{ key: OPSLOG_CONF, label: t('qedit.confOpsLog') },
|
||||
{ key: HAMLOG_CONF, label: 'HAMLOG.online' },
|
||||
{ key: HAMQTH_CONF, label: 'HamQTH' },
|
||||
]).map((c) => <SelectItem key={c.key} value={c.key}>{c.label}</SelectItem>)}
|
||||
{/* The three above that are NOT in CONFIRMATIONS — the
|
||||
QSO columns, and this channel lives in the ADIF
|
||||
extras. It gets its own editor below rather than the
|
||||
generic sent/received/date grid, which has no field
|
||||
to bind to. */}
|
||||
<SelectItem value={OPSLOG_CONF}>{t('qedit.confOpsLog')}</SelectItem>
|
||||
<SelectItem value={HAMLOG_CONF}>HAMLOG.online</SelectItem>
|
||||
<SelectItem value={HAMQTH_CONF}>HamQTH</SelectItem>
|
||||
OpsLog card, HAMLOG.online and HamQTH — are backed by
|
||||
ADIF extras rather than QSO columns, and each gets its
|
||||
own editor below instead of the generic
|
||||
sent/received/date grid, which has no field to bind
|
||||
to. */}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
@@ -865,37 +882,32 @@ export function QSOEditModal({ qso, onSave, onDelete, onClose, countries = [], b
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{CONFIRMATIONS.map((c) => (
|
||||
{/* The extras-backed channels (OpsLog card,
|
||||
HAMLOG.online, HamQTH) sit in the same ordered list
|
||||
as the column-backed ones: the reader is looking for
|
||||
a name, not for a storage detail. A dash in RECEIVED
|
||||
means the channel has nothing to receive — Club Log
|
||||
and HamQTH publish no confirmations — which is not
|
||||
the same statement as "N". */}
|
||||
{confOrder([
|
||||
...CONFIRMATIONS.map((c) => ({
|
||||
key: c.key,
|
||||
label: CONF_LABEL_KEYS[c.key] ? t(CONF_LABEL_KEYS[c.key]) : c.label,
|
||||
sent: val(c.sent),
|
||||
rcvd: c.rcvd ? val(c.rcvd) : null,
|
||||
})),
|
||||
{ key: OPSLOG_CONF, label: t('qedit.confOpsLog'), sent: opslogQslSent ? 'Y' : 'N', rcvd: qslReceived ? 'Y' : 'N' },
|
||||
{ key: HAMLOG_CONF, label: 'HAMLOG.online', sent: exVal(HAMLOG_KEYS.sent), rcvd: exVal(HAMLOG_KEYS.rcvd) },
|
||||
{ key: HAMQTH_CONF, label: 'HamQTH', sent: exVal(HAMQTH_KEYS.sent), rcvd: null },
|
||||
]).map((c) => (
|
||||
<tr key={c.key} className="text-xs">
|
||||
<td className="font-medium pr-3 py-0.5 whitespace-nowrap">{CONF_LABEL_KEYS[c.key] ? t(CONF_LABEL_KEYS[c.key]) : c.label}</td>
|
||||
<td className="w-24"><StatusCell value={val(c.sent)} /></td>
|
||||
<td className="w-24">{c.rcvd ? <StatusCell value={val(c.rcvd)} /> : <span className="block text-center text-[11px] text-muted-foreground">—</span>}</td>
|
||||
<td className="font-medium pr-3 py-0.5 whitespace-nowrap">{c.label}</td>
|
||||
<td className="w-24"><StatusCell value={c.sent} /></td>
|
||||
<td className="w-24">{c.rcvd === null
|
||||
? <span className="block text-center text-[11px] text-muted-foreground">—</span>
|
||||
: <StatusCell value={c.rcvd} />}</td>
|
||||
</tr>
|
||||
))}
|
||||
{/* OpsLog's own card, read from the ADIF extras rather
|
||||
than a QSO column — hence a hand-written row instead
|
||||
of a CONFIRMATIONS entry. "Sent" is stamped by OpsLog
|
||||
when the card actually goes out, so it stays
|
||||
read-only here: an operator ticking it by hand would
|
||||
be recording something that never happened. */}
|
||||
<tr className="text-xs">
|
||||
<td className="font-medium pr-3 py-0.5 whitespace-nowrap">{t('qedit.confOpsLog')}</td>
|
||||
<td className="w-24"><StatusCell value={opslogQslSent ? 'Y' : 'N'} /></td>
|
||||
<td className="w-24"><StatusCell value={qslReceived ? 'Y' : 'N'} /></td>
|
||||
</tr>
|
||||
{/* HAMLOG.online — extras again, same hand-written row. */}
|
||||
<tr className="text-xs">
|
||||
<td className="font-medium pr-3 py-0.5 whitespace-nowrap">HAMLOG.online</td>
|
||||
<td className="w-24"><StatusCell value={exVal(HAMLOG_KEYS.sent)} /></td>
|
||||
<td className="w-24"><StatusCell value={exVal(HAMLOG_KEYS.rcvd)} /></td>
|
||||
</tr>
|
||||
{/* HamQTH — sent only; the dash says there is nothing
|
||||
to receive, not that nothing was received. */}
|
||||
<tr className="text-xs">
|
||||
<td className="font-medium pr-3 py-0.5 whitespace-nowrap">HamQTH</td>
|
||||
<td className="w-24"><StatusCell value={exVal(HAMQTH_KEYS.sent)} /></td>
|
||||
<td className="w-24"><span className="block text-center text-[11px] text-muted-foreground">—</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user