Skip to content

feat(desktop): searchable timezone picker in Settings → Chat (salvage #68969) - #73505

Merged
teknium1 merged 4 commits into
mainfrom
hermes/hermes-133bac7c
Jul 28, 2026
Merged

feat(desktop): searchable timezone picker in Settings → Chat (salvage #68969)#73505
teknium1 merged 4 commits into
mainfrom
hermes/hermes-133bac7c

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Desktop Settings → Chat → Timezone is now a searchable, validated IANA timezone picker instead of a free-text input that accepted any string. Salvages PR #68969 by @DavidMetcalfe onto current main with authorship preserved, plus follow-up tests and locale coverage. Closes #68970.

Root cause of the report ("I can type anything in it"): timezone had no schema override, so ConfigField fell through to the generic free-text <Input> branch — the backend fails safe on invalid values (falls back to server-local with a log warning), but the UI validated nothing.

Changes

  • hermes_cli/web_server.py: timezone schema override — select with sorted zoneinfo.available_timezones() (UTC fallback), new generic searchable + clearable schema flags.
  • apps/desktop/.../searchable-select.tsx: new SearchableSelect (Popover + cmdk) with segment-ranked filtering ("york" → America/New_York) and a "System default" clear item; filter extracted to exported rankSearchOption.
  • apps/desktop/.../config-field.tsx: routes schema.searchable === true to SearchableSelect.
  • i18n: searchPlaceholder / noResults / systemDefault in en + zh (contributor) and ja + ar + zh-hant (follow-up).
  • Tests (follow-up): 12 vitest cases (filter ranking, select/clear/placeholder, ConfigField routing) + backend invariant test in tests/hermes_cli/test_web_server.py (sabotage-verified: fails on unfixed main).

Validation

Before After
Timezone field free-text, accepts any string searchable select, 486 IANA ids
Revert to system default delete text "System default" clear item
vitest searchable-select.test.tsx 12/12 pass
pytest test_web_server.py -k timezone/Schema 15/15 pass
npm run typecheck, eslint, prettier clean

Credit

Original implementation by @DavidMetcalfe (#68969), cherry-picked with authorship preserved. Supersedes #38607 by @CyrisXD — the earlier attempt at the same feature.

Infographic

infographic

DavidMetcalfe and others added 4 commits July 28, 2026 10:09
The timezone field was a free-text input with no guidance on format.
Users had to know the exact IANA identifier (e.g. America/New_York)
to configure it. Replace it with a searchable combobox built on
Popover + cmdk Command — the same stack as Shadcn's Combobox.

Backend:
- Add `_timezone_options()` to web_server.py (cached at import time,
  returns sorted zoneinfo.available_timezones() — ~598 identifiers)
- Add `"timezone"` to `_SCHEMA_OVERRIDES` with `type: "select"`,
  `options`, and `searchable: true`

Frontend:
- New `SearchableSelect` component (Popover + cmdk Command)
  — closed-world filterable dropdown for large option lists
- `ConfigField` routes to `SearchableSelect` when
  `schema.searchable === true` (explicit opt-in, no threshold)
- Add `searchable?: boolean` to `ConfigFieldSchema` type
- Add i18n keys: `searchPlaceholder`, `noResults`

The `searchable` flag is deterministic — no existing field is
affected unless explicitly opted in. Future large-list fields
can adopt the same pattern by adding `searchable: true` to their
schema override.
- Fix focus: use autoFocus on CommandInput instead of e.preventDefault()
- Fix filter: prioritize city segment match (return 2 for slash match)
- Fix handleSelect: always select, don't toggle-deselect
- Add aria-haspopup to trigger button
- Use defensive placeholder logic
…, UTC fallback

- Add 'System default' clear option to SearchableSelect via clearLabel prop
- Add clearable flag to ConfigFieldSchema (schema-driven, not hardcoded)
- Add clearable: true to timezone schema override in web_server.py
- Fix CommandItem value for clear item: use clearLabel instead of '' so
  cmdk can match it during search
- Fix backend: or ['UTC'] fallback for hosts without tzdata where
  available_timezones() returns an empty set (not an exception)
- Add systemDefault i18n key (en, types, zh)
- Extract the cmdk filter into exported rankSearchOption and cover it,
  SearchableSelect selection/clear/placeholder, and ConfigField
  searchable-schema routing with 12 vitest cases (sabotage-verified:
  the backend schema test fails on unfixed main).
- Add searchPlaceholder/noResults/systemDefault strings to ja/ar/zh-hant
  (zh + en came with the salvaged commits; defineLocale would have
  fallen back to English otherwise).
- Add a backend invariant test: timezone ships as a searchable,
  clearable select of sorted IANA ids with a UTC fallback.
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 8b11503

ℹ️ Info

Desktop E2E visual evidence · View test artifacts · View job

1 visual diff.

inline evidence is publishing...

@DavidMetcalfe

Copy link
Copy Markdown
Contributor

Thanks for salvaging this! I've closed #68969 as superseded by this PR.

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.

[Feature]: searchable timezone dropdown in Desktop Settings

2 participants