fix: don't close the active comment panel when a different comment is resolved (#39491)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
David Park 2026-07-24 06:11:25 +00:00 committed by GitHub
parent 6e2c21f568
commit 3ab9e083e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 67 additions and 1 deletions

View File

@ -669,4 +669,68 @@ describe('useWorkflowComment', () => {
expect(store.getState().pendingComment).toBeNull()
})
it('does not overwrite the active comment when a different comment is resolved/refreshed', async () => {
const commentA = baseComment()
const commentB: WorkflowCommentList = {
...baseComment(),
id: 'comment-2',
content: 'second',
position_x: 50,
position_y: 80,
}
const activeBDetail = { ...baseCommentDetail(), id: commentB.id, content: 'B detail' }
// refreshActiveComment(A) — reached via resolving A — fetches A's detail:
mockFetchWorkflowComment.mockResolvedValue({
...baseCommentDetail(),
id: commentA.id,
content: 'A detail (must not clobber B)',
})
mockResolveWorkflowComment.mockResolvedValue({})
mockFetchWorkflowComments.mockResolvedValue({
data: [{ ...commentA, resolved: true }, commentB],
})
const { result, store } = renderWorkflowHook(() => useWorkflowComment(), {
queryClient: createSeededQueryClient(),
initialStoreState: {
comments: [commentA, commentB],
activeCommentId: commentB.id,
activeCommentDetail: activeBDetail,
},
})
await act(async () => {
await result.current.handleCommentResolve(commentA.id)
})
// B is still the selected comment; A's fetched detail must not replace it.
expect(store.getState().activeCommentId).toBe(commentB.id)
expect(store.getState().activeCommentDetail?.id).toBe(commentB.id)
})
it('still refreshes the active comment', async () => {
const commentA = baseComment()
mockFetchWorkflowComment.mockResolvedValue({
...baseCommentDetail(),
id: commentA.id,
content: 'refreshed content',
})
const { result, store } = renderWorkflowHook(() => useWorkflowComment(), {
queryClient: createSeededQueryClient(),
initialStoreState: {
comments: [commentA],
activeCommentId: commentA.id,
activeCommentDetail: { ...baseCommentDetail(), id: commentA.id, content: 'stale content' },
},
})
await act(async () => {
await result.current.refreshActiveComment(commentA.id)
})
expect(store.getState().activeCommentDetail?.id).toBe(commentA.id)
expect(store.getState().activeCommentDetail?.content).toBe('refreshed content')
})
})

View File

@ -98,7 +98,9 @@ export const useWorkflowComment = () => {
[commentId]: detail,
}
setCommentDetailCache(commentDetailCacheRef.current)
setActiveComment(detail)
// Only apply the fetched detail if this comment is still the active one;
// otherwise a refresh for another comment can clobber the current selection.
if (activeCommentIdRef.current === commentId) setActiveComment(detail)
},
[appId, setActiveComment, setCommentDetailCache],
)