Skip to content

feat(ui): business-friendly quick add flow with keyboard shortcut N (SPEC-002, Task 102b9a48) - #113

Merged
JustAGhosT merged 3 commits into
mainfrom
feat/102b9a48-quick-add
Aug 14, 2026
Merged

feat(ui): business-friendly quick add flow with keyboard shortcut N (SPEC-002, Task 102b9a48)#113
JustAGhosT merged 3 commits into
mainfrom
feat/102b9a48-quick-add

Conversation

@JustAGhosT

Copy link
Copy Markdown
Collaborator

Summary

  • Implements SPEC-002 business-friendly quick add flow for Baton task 102b9a48.
  • Created \QuickAddModal.tsx\ component with auto-focused title input, project/column/priority selectors, quick estimate pills (\1, \2, \3, \5, \8), human/agent assignee picker, and work type selector.
  • Built smart title inline syntax parser supporting !high\ / !critical\ priority tags and @5PT\ / @3\ estimate tags.
  • Added global keyboard shortcut listener for \N\ key (safely suppressed inside inputs/textareas).
  • Supported \Enter\ (create & close) and \Shift+Enter\ (create & open detail overlay).
  • Integrated + Quick Add\ button with keyboard badge into \Header.tsx.
  • Verified with 53 passing Vitest unit tests and clean production build.

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@JustAGhosT, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 26 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 43ce0eab-3c69-4759-b5e6-f98a40b8442a

📥 Commits

Reviewing files that changed from the base of the PR and between 5e2717b and b813fcd.

📒 Files selected for processing (4)
  • frontend/src/App.tsx
  • frontend/src/components/Header.tsx
  • frontend/src/components/QuickAddModal.test.ts
  • frontend/src/components/QuickAddModal.tsx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@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: c5d3263303

ℹ️ 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".

priority: finalPriority,
status,
estimate: finalEstimate,
ownerType: assigneeType,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Omit unassigned ownership for ordinary creators

When authentication is enabled and the caller has the ordinary user role, every quick-add request includes ownerType: 'unassigned'; the POST handler treats the presence of any ownership field as an assignment operation, so canAssignTasks rejects the request with 403 even though an otherwise identical create without ownership fields is allowed. Omit ownerType when no assignee was chosen so non-manager users can use the new flow.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in b813fcd: unassigned quick-add no longer sends ownerType. Assignment fields are only included when the user picks a human or agent.

Comment on lines +174 to +176
if (e.key === 'Enter') {
e.preventDefault();
handleCreate(e.shiftKey || e.metaKey || e.ctrlKey);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Block repeat Enter submissions while pending

During a slow create request, the title input remains active and every Enter keydown calls handleCreate without checking isSubmitting. Pressing Enter twice or holding the key can therefore issue multiple POSTs and create duplicate tasks even though the footer buttons are disabled; ignore keyboard submission while a request is pending.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in b813fcd: handleCreate and Enter return immediately while isSubmitting is true, so repeat Enter cannot create duplicates.

Comment on lines +115 to +118
const estMatch = clean.match(/@(\d+(?:\.\d+)?)(?:pt|h)?/i);
if (estMatch) {
parsedEstimate = parseFloat(estMatch[1]);
clean = clean.replace(estMatch[0], '');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restrict smart syntax to standalone tokens

Because the estimate pattern has no token boundary and its unit is optional, ordinary titles containing numeric package/version notation are silently rewritten: for example, Upgrade React@18 becomes title Upgrade React with estimate 18. Require whitespace/token boundaries around inline shortcuts so valid title text is not removed.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in b813fcd: !priority and @estimate now require token boundaries, so Upgrade React@18 stays a title.

Comment on lines +147 to +149
const task = await onSubmit({
projectId,
title,

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 Keep cross-project creates off the active board

When viewing project A, the project selector permits creating in project B, but App forwards the request through the project-A-scoped useTasks.createTask, which unconditionally appends the returned task to its local list. The project-B task consequently appears on project A's board until a refetch; either switch/refetch the selected project or avoid appending creates outside the active project.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in b813fcd: creating in another project calls api.createTask directly and does not append that task to the current board list.

Comment thread frontend/src/App.tsx Outdated
Comment on lines +219 to +221
if ((e.key === 'n' || e.key === 'N') && !e.metaKey && !e.ctrlKey && !e.altKey) {
e.preventDefault();
setQuickAddOpen(true);

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 Use the required T shortcut

The implemented global shortcut listens for N, while the acceptance criterion in docs/plans/baton-ux-sprint-r13.md:114 and SPEC-002 both assign Quick Add to T. Keyboard users following the documented workflow therefore cannot open the drawer with the promised key; align the listener and displayed badges with T.

AGENTS.md reference: AGENTS.md:L8-L8

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in b813fcd: the global shortcut, header badge, and modal hint now use T as specified by SPEC-002 / the sprint plan.

Comment on lines +65 to +70
useEffect(() => {
if (isOpen) {
setProjectId(selectedProjectId || projects[0]?.id || '');
setRawTitle('');
setError(null);
setTimeout(() => inputRef.current?.focus(), 50);

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 Reset all fields for each quick-add session

Closing and reopening the modal resets only the title, project, and error; status, priority, estimate, assignee, and work type retain their previous values. After creating or abandoning a specialized task, a subsequent quick add can silently inherit values such as done, critical, or an agent assignee instead of starting from the advertised defaults.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in b813fcd: opening the modal resets title, description, status, priority, estimate, assignee, work type, and error.

Comment on lines +212 to +218
<input
ref={inputRef}
type="text"
value={rawTitle}
onChange={e => setRawTitle(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="What needs to be done? (Use @5pt or !high for quick formatting)..."

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 Add the optional description field

The quick-add body goes directly from the title input to metadata controls, leaving no way to enter the optional description required by docs/plans/baton-ux-sprint-r13.md:115, even though the submit contract already accepts description. Users must create and reopen every task that needs context, so expose and forward a description field in this flow.

AGENTS.md reference: AGENTS.md:L8-L8

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in b813fcd: Quick Add now has an optional description field and forwards it on create.

@JustAGhosT

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Use T to open, omit unassigned ownerType, block repeat Enter, keep
inline shortcuts token-bounded, reset all fields, add description,
and do not append cross-project creates onto the active board.
@JustAGhosT
JustAGhosT merged commit a0fc605 into main Aug 14, 2026
3 checks passed
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