Skip to content

ProjectTaskPicker — combined picker fixes missing task select in popover#29

Merged
mariomeyer merged 3 commits into
mainfrom
fix/project-task-picker
Jun 16, 2026
Merged

ProjectTaskPicker — combined picker fixes missing task select in popover#29
mariomeyer merged 3 commits into
mainfrom
fix/project-task-picker

Conversation

@mariomeyer

Copy link
Copy Markdown
Member

Summary

  • New ProjectTaskPicker combined component — tree dropdown with project headers + indented tasks. Project rows are selectable (project-only); task rows yield project + task atomically.
  • Wired into Popover.tsx (fixes the actual bug — the popover had no task picker at all post-6c), TimerCard.tsx (replaces ProjectPicker+TaskPicker pair in start form + live entry), and EditEntryDialog.tsx (same).
  • Existing simpler ProjectPicker stays in use for Settings (default project) and CalendarSection (calendar default project) — those genuinely want project-only.

UX details

  • Tree layout: project headers bold with chevron; tasks indented .
  • "(No project)" sentinel at top, always visible.
  • All collapsed by default; the project containing the currently-selected task auto-expands when the dropdown opens.
  • Smart search: filters both levels; tasks matching the query auto-expand their parent (parent shown dimmed when only children match).
  • Keyboard: ↑↓ traverse visible rows, Enter selects, Esc closes, Right expands, Left collapses (or jumps task → parent).
  • Tasks marked done are excluded.

Test plan

  • CI: typecheck clean
  • CI: 11 new picker unit tests + 268 prior UI tests = 279 total green
  • CI: rust + Swift suites unaffected (no Rust changes)
  • Manual: install local notarized build → open popover → start form picker shows projects + their tasks indented + lets you pick a task
  • Manual: TimerCard start form + live-entry inline edit work via the new picker
  • Manual: EditEntryDialog opens with project / task pre-selected; switching project + task in one click works

🤖 Generated with Claude Code

…ct in popover

Single combobox replacing the ProjectPicker+TaskPicker pair wherever both
are used together. Tree layout: "(No project)" sentinel at top, project
headers rendered bold with a chevron, tasks indented underneath. Project
rows are selectable (selecting one yields project-only, task_id=null).

Smart search: typing filters both projects and tasks. Tasks matching the
query auto-expand their parent project; if the parent's name doesn't
match the parent shows dimmed (still clickable for project-only). All
projects collapsed by default; opening the dropdown with a current
task selected auto-expands its parent so the value is visible.

Keyboard: ↑↓ traverse visible rows, Enter selects, Esc closes, Right
expands a collapsed project, Left collapses an expanded one (or jumps
from a task back to its parent).

Why: the popover had no TaskPicker at all (regression from 6c — the
parallel task-assignment work added TaskPicker to TimerCard +
EditEntryDialog but missed the popover route). Adding a second
combobox there would crowd the layout; the combined picker handles it
naturally and brings the same unified shape to TimerCard and the
EditEntryDialog.

The simpler ProjectPicker stays in use for Settings (default project)
and CalendarSection (calendar default project) — those genuinely want
project-only and no tasks.

Tests: 11 new unit tests covering placeholder/value rendering, click +
keyboard selection, auto-expand on selected-task, smart search filter,
done-task exclusion, and the empty-state message. Existing tests for
TimerCard, EditEntryDialog, EntryRow, Today, and Popover updated to
match the new aria-label and combined layout.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4673278351

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/routes/Popover.tsx
projectId() || undefined,
undefined,
projectId() ?? undefined,
taskId() ?? undefined,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear the popover task selection after starting a timer

When a timer is started from the menu-bar popover with a task selected, the success callback at lines 102–106 resets the description, billable flag, and start time but leaves taskId unchanged. After the user stops that timer, the next popover form therefore remains preselected to the previous task and this argument silently assigns a subsequent timer to it unless the user explicitly clears the picker. The main-window TimerCard clears its task selection after a successful start, and the popover should do the same while preserving the existing project-retention behavior.

Useful? React with 👍 / 👎.

Three iteration tweaks based on local testing:

1. Chevron clarity — bigger button (h-6 w-6 instead of h-4 w-4), SVG
   caret instead of unicode ▸/▾, only rendered for projects that
   actually have tasks. Projects without tasks get a bullet • in the
   same column so the layout aligns and they don't hint at expansion.

2. Search expansion stickiness — split expansion into user-driven and
   search-driven sets. Clearing the query collapses search-only
   expansions back; user-driven expansions persist.

3. Task styling — drop the ↳ prefix, indent more (w-6 spacer + w-4
   dash column), smaller font (text-xs) + muted color (text-zinc-600).
   Tasks now get a leading – instead of ↳.

3 new tests for the search-expansion separation + chevron-absence on
empty projects. Total 14 picker tests.
Codex flagged on PR #29: the popover's success callback resets
description / billable / startAt but leaves taskId in place. Result —
after the user stops a timer started with a task, the next popover
start silently inherits that task unless they explicitly clear the
picker. TimerCard already clears both project and task; the popover
was the inconsistent one.

Fix only resets taskId. projectId stays — the pre-picker popover
preserved project across back-to-back timer starts and users rely on
that for working on the same project repeatedly.
@mariomeyer mariomeyer merged commit 752d1d9 into main Jun 16, 2026
2 checks passed
@mariomeyer

Copy link
Copy Markdown
Member Author

🎉 This PR is included in version 0.5.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant