Skip to content

feat(search): offer every stored mode in the mode filter (JS8/FST4/JT65/Q65/Olivia/…)#242

Merged
patrickrb merged 1 commit into
mainfrom
optio/task-1372c3c4-7364-44f8-8668-f98fddbdccdd
Jul 24, 2026
Merged

feat(search): offer every stored mode in the mode filter (JS8/FST4/JT65/Q65/Olivia/…)#242
patrickrb merged 1 commit into
mainfrom
optio/task-1372c3c4-7364-44f8-8668-f98fddbdccdd

Conversation

@patrickrb

Copy link
Copy Markdown
Owner

Problem

The Search page's Mode filter drew from a hard-coded 12-entry list
(['AM','FM','FT8','MFSK','RTTY','SSB','CW','FT4','PSK31','DMR','DSTAR','YSF']).
Among digital modes it only knew FT4/FT8/PSK31/MFSK.

But Nextlog can store many more modes than that. ADIF import promotes a
WSJT-X / fldigi SUBMODE to the effective mode (resolveAdifMode in
@/lib/adif, added in #240) — so a run logged under the generic MFSK/PSK
parent lands in the log as JS8, FST4, JT65, JT9, Q65, PSK63,
OLIVIA, CONTESTIA, etc. None of those appeared in the dropdown, so those
QSOs were unfilterable by mode — the exact class of drift bug #241 fixed
for the band filter.

Solution

Introduce a canonical mode list at src/lib/modes.ts — a server-imports-free
single source of truth, mirroring src/lib/bands.ts (AMATEUR_BANDS) — and
point the search filter at it via AMATEUR_MODES. The list covers the modes
the logging forms offer, the popular weak-signal digital modes, keyboard/FSK
modes, SSTV, and the digital-voice modes, ordered so everyday modes sit at the
top of the dropdown.

Mode matching is already case-insensitive on the server
(UPPER(mode) = UPPER($n) in @/lib/contact-search), so the uppercase values
match whatever import/logging stored. No API or schema change; every mode the
old list offered is retained (no regression).

Testing

  • New: tests/modes.spec.ts guards the source of truth (no duplicates,
    canonical uppercase, covers logging-form modes, covers the import-promoted
    submodes, retains the legacy list, and keeps the everyday modes at the top) —
    same spirit as tests/bands.spec.ts.
  • npx playwright test tests/modes.spec.ts tests/bands.spec.ts → 10 passed.
  • npm run typecheck → clean.
  • npm run lint → clean.
  • npm run build → succeeds (/search compiles); the only build failure seen
    locally was an offline Google-Fonts fetch, unrelated to this change.

Future follow-up

  • The logging forms (new-contact, QuickLogCard) still offer their own
    shorter 8-mode menu; a later sweep could source them from AMATEUR_MODES
    too (kept out of scope here to avoid touching RST-default logic).
  • The filter-chips-demo page keeps its own copy of the old list — it's a
    demo, not product surface, so it was left untouched.

🤖 Generated with Claude Code

…65/Q65/PSK63/Olivia/…)

The search mode dropdown hard-coded a 12-entry list that, among digital
modes, only knew FT4/FT8/PSK31/MFSK. But ADIF import promotes a WSJT-X /
fldigi SUBMODE to the effective mode (resolveAdifMode in @/lib/adif), so a
QSO can land in the log as JS8, FST4, JT65, JT9, Q65, PSK63, Olivia or
Contestia — none of which the dropdown offered, leaving those contacts
unfilterable by mode.

Introduce a canonical mode list at @/lib/modes (mirroring @/lib/bands: a
server-imports-free single source of truth) and point the search filter at
it. Matching is already case-insensitive on the server
(UPPER(mode) = UPPER($n)), so the uppercase values match stored data.

Guarded by tests/modes.spec.ts, in the same spirit as bands.spec.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nodelog Ready Ready Preview, Comment Jul 24, 2026 8:09am

Request Review

@patrickrb
patrickrb merged commit b3d1f6d into main Jul 24, 2026
5 checks passed
patrickrb added a commit that referenced this pull request Jul 24, 2026
The Quick Log card and the full new-contact form both hard-coded an
8-mode menu (SSB/CW/FT8/FT4/RTTY/PSK31/AM/FM). Search already offers the
full canonical mode list (#242) and ADIF import promotes submodes like
JS8/FST4/JT65/Q65/PSK63/Olivia — so an operator could import or filter
those modes but could not *log* one without editing the QSO afterward.

Both forms now draw their menu from the canonical AMATEUR_MODES, exactly
as they already do for AMATEUR_BANDS. The per-mode RST default heuristic
(duplicated and drifting between the two forms) is centralized as
modes.defaultRstForMode, preserving the classification each form used.

Co-authored-by: Optio Agent <optio-agent@noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant