LearningCircuit/local-deep-research

Zotero page UX: smoother collection selection and friendlier sync feedback

Open

#4,961 opened on Jul 4, 2026

View on GitHub
 (2 comments) (0 reactions) (0 assignees)Python (776 forks)auto 404
enhancementgood first issuehelp wantedui-ux

Repository metrics

Stars
 (8,787 stars)
PR merge metrics
 (PR metrics pending)

Description

Summary

The Zotero integration (#4723, #4960) works end-to-end, but parts of the page UX are still clunky — especially how collections are chosen. Plenty of self-contained, UI-only improvements here; a good place to make a first contribution.

Current behavior (what feels clunky)

  1. Choosing collections is fiddly. Collections live in a plain comma-separated text field of opaque keys (e.g. W63I9K8W) inside the "Advanced options" section. The picker is a separate card at the bottom of the page: clicking a key appends it to the text field back at the top. Removing a collection means hand-editing the comma list. There are no checkboxes, no names next to the selected keys, no visual link between the picker and the field.
  2. The sync-status table shows raw collection keys, not names — "W63I9K8W" instead of "test". Users have to remember what a key means.
  3. The group picker has the same shape: a separate bottom card that silently rewrites two fields in Advanced.
  4. Feedback is split across two channels: the app-wide banner (autosave results) and an inline message area under the action buttons (test/sync/picker results). Users have to watch two places.
  5. Sync results are thin: after a sync you see status/item-count per collection, but the imported/skipped/errors counts from the run are only visible in server logs.

Suggested direction

Replace the text-field + bottom-card pattern with an inline, name-based multi-select directly under the Collections field (see the implementation notes in the first comment). Show collection names in the status table. Fold group selection into the library-type row. Surface the last sync's imported/skipped/errors counts in the status area.

Small, independent slices — each bullet above is shippable on its own.

Constraints to respect

  • All dynamic values inserted via innerHTML must go through the page's esc() helper (XSS).
  • CSS classes must carry the ldr- prefix (pre-commit enforces this).
  • Autosave is gated on configLoadState === 'ready' — new controls must save through autosave() and respect that gate.
  • The API key is write-only; nothing may echo it back to the page.
  • tests/ui_tests/test_zotero_integration_ci.js pins element ids and page structure — update it in lockstep with any markup changes.

Contributor guide