feat: show linked issues#1852
Conversation
Greptile SummaryThis PR adds "already linked" indicators to both issue selector components so users can see at a glance which issues are already attached to another agent task, preventing duplicate linking. Issues are surfaced via a new
Confidence Score: 4/5Safe to merge with the initial highlighted-index bug addressed first. One P1 issue: setHighlightedIndex(0) in handleQueryChange/handleProviderChange can place the cursor on a disabled linked item, making it invisible and silently blocking Enter. All other logic is sound. src/renderer/features/tasks/components/issue-selector/inline-issue-selector.tsx — handleQueryChange and handleProviderChange need the same skip-linked logic used by ArrowDown.
|
| Filename | Overview |
|---|---|
| src/renderer/features/tasks/components/issue-selector/use-linked-issue-urls.ts | New helper that iterates observable task state to build an issue-URL → task-info map; correctly excludes archived tasks and the current task via excludeTaskId. |
| src/renderer/features/tasks/components/issue-selector/inline-issue-selector.tsx | Wraps component in observer and adds linked-issue awareness; arrow-key navigation correctly skips linked items, but setHighlightedIndex(0) in handleQueryChange/handleProviderChange can silently place the cursor on a disabled item. |
| src/renderer/features/tasks/components/issue-selector/issue-selector.tsx | Adds LinkedToTaskBadge and IssueRow linkedTo prop; IssueSelector wraps with observer and disables ComboboxItems for already-linked issues. |
| src/renderer/features/tasks/task-titlebar.tsx | Passes excludeTaskId={taskId} to IssueSelector so the current task's own issue isn't shown as already-linked. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User opens issue selector] --> B[getLinkedIssueMap called\ninside observer component]
B --> C{projectId\nprovided?}
C -- No --> D[Return empty Map]
C -- Yes --> E[Iterate taskManager.tasks]
E --> F{isRegistered &\nnot archived &\nnot excludeTaskId?}
F -- Yes --> G[Add issue URL →\nLinkedIssueInfo to Map]
F -- No --> E
G --> H[Map passed to IssueRow]
H --> I{issue.url in Map?}
I -- Yes --> J[Render LinkedToTaskBadge\n+ disable item]
I -- No --> K[Render normal selectable item]
J --> L[ArrowDown/Up skips\ndisabled items]
K --> L
Comments Outside Diff (1)
-
src/renderer/features/tasks/components/issue-selector/inline-issue-selector.tsx, line 66-73 (link)Initial cursor position ignores linked items after query/provider change
handleQueryChange(line 71) andhandleProviderChange(line 82) both callsetHighlightedIndex(0)unconditionally. If the first result in the new list is a linked issue, the cursor lands on a disabled item: the highlight is invisible (isHighlighted && !isSelected && !isLinkedblocks the background), and pressing Enter silently does nothing. The ArrowDown fix in this PR only helps once the user already knows to press it. The initialisation step should forward-scan for the first non-linked index, the same way ArrowDown does.Prompt To Fix With AI
This is a comment left during a code review. Path: src/renderer/features/tasks/components/issue-selector/inline-issue-selector.tsx Line: 66-73 Comment: **Initial cursor position ignores linked items after query/provider change** `handleQueryChange` (line 71) and `handleProviderChange` (line 82) both call `setHighlightedIndex(0)` unconditionally. If the first result in the new list is a linked issue, the cursor lands on a disabled item: the highlight is invisible (`isHighlighted && !isSelected && !isLinked` blocks the background), and pressing Enter silently does nothing. The ArrowDown fix in this PR only helps once the user already knows to press it. The initialisation step should forward-scan for the first non-linked index, the same way ArrowDown does. How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
src/renderer/features/tasks/components/issue-selector/inline-issue-selector.tsx:66-73
**Initial cursor position ignores linked items after query/provider change**
`handleQueryChange` (line 71) and `handleProviderChange` (line 82) both call `setHighlightedIndex(0)` unconditionally. If the first result in the new list is a linked issue, the cursor lands on a disabled item: the highlight is invisible (`isHighlighted && !isSelected && !isLinked` blocks the background), and pressing Enter silently does nothing. The ArrowDown fix in this PR only helps once the user already knows to press it. The initialisation step should forward-scan for the first non-linked index, the same way ArrowDown does.
Reviews (2): Last reviewed commit: "fix: skip linked issues in keyboard nav,..." | Re-trigger Greptile
| disabled, | ||
| excludeTaskId, | ||
| }: InlineIssueSelectorProps) { | ||
| const linkedIssueMap = getLinkedIssueMap(projectId, excludeTaskId); |
There was a problem hiding this comment.
New
Map instance on every render invalidates useCallback
getLinkedIssueMap returns a freshly constructed Map on every render. Because linkedIssueMap is included in the dependency array of handleKeyDown (line 114), the callback is recreated on every render — negating the memoization benefit. Consider stabilising the reference via useMemo(() => getLinkedIssueMap(projectId, excludeTaskId), [projectId, excludeTaskId]), so the map only rebuilds when the underlying observable data actually changes.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/renderer/features/tasks/components/issue-selector/inline-issue-selector.tsx
Line: 37
Comment:
**New `Map` instance on every render invalidates `useCallback`**
`getLinkedIssueMap` returns a freshly constructed `Map` on every render. Because `linkedIssueMap` is included in the dependency array of `handleKeyDown` (line 114), the callback is recreated on every render — negating the memoization benefit. Consider stabilising the reference via `useMemo(() => getLinkedIssueMap(projectId, excludeTaskId), [projectId, excludeTaskId])`, so the map only rebuilds when the underlying observable data actually changes.
How can I resolve this? If you propose a fix, please make it concise.Address PR review: - ArrowDown/ArrowUp now skip past linked (disabled) issues so the highlight is always visible and Enter never silently no-ops. - Hold linkedIssueMap in a ref and drop it from handleKeyDown deps so the callback is no longer recreated every render. (useMemo here would break MobX reactivity — observables wouldn't be re-read on cached renders, leaving the map stale.) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@greptile review |
|
are issues that are already linked to a task disabled in this implementation? |
show which tasks are already linked to an agent to avoid doing stuff double :D