Migrate PR mutations from methods on PRReviewStore to useMutation hooks. Delete the mutation state (merging, mergeError, dequeueing, etc.) from the store.
Methods migrated
Each becomes a useMutation hook in src/browser/lib/mutations.ts:
mergePR → useMergePR
dequeuePR → useDequeuePR
closePR → useClosePR
reopenPR → useReopenPR
deleteBranch → useDeleteBranch
restoreBranch → useRestoreBranch
convertToDraft → useConvertToDraft
markReadyForReview → useMarkReadyForReview
updatePR → useUpdatePR
updateBranch → useUpdateBranch
approveWorkflows → useApproveWorkflows
getRepoBranches → useRepoBranches (query, not mutation, but currently lives with these)
Store fields removed
merging, mergeError, mergeMethod (setter stays — setMergeMethod — since mergeMethod is a UI selection, not fetched state — reconsider during implementation)
dequeueing, closingPR, reopeningPR, deletingBranch, restoringBranch
convertingToDraft, convertingToDraftError
markingReady, markingReadyError
approvingWorkflows, updatingPR
Consumers read mutation.isPending / mutation.error instead.
Optimistic + invalidation pattern
Each mutation's onMutate should apply the same optimistic setQueryData calls the store used to do inline. onSuccess (or onSettled) invalidates:
mergePR → invalidate PR, timeline, comments, reviews, checks.
closePR / reopenPR → invalidate PR + timeline.
deleteBranch / restoreBranch → invalidate branch status + PR.
convertToDraft / markReadyForReview → invalidate PR + timeline.
updatePR → invalidate PR + timeline.
approveWorkflows → invalidate workflow runs + checks.
Consumer changes
pr-overview.tsx, pr-edit-dialog.tsx, and anywhere a merge/close/reopen button lives — swap method calls for mutation .mutate(); swap in-flight flag reads for mutation.isPending.
Tests
Per mutation hook:
- Optimistic-update path: cache reflects the change immediately.
- Success path: cache reconciled with server response, correct queries invalidated.
- Error path: optimistic update rolled back, error surfaces to
mutation.error.
Delete corresponding store mutation-method tests.
Part of #351
Depends on #353.
Migrate PR mutations from methods on
PRReviewStoretouseMutationhooks. Delete the mutation state (merging,mergeError,dequeueing, etc.) from the store.Methods migrated
Each becomes a
useMutationhook insrc/browser/lib/mutations.ts:mergePR→useMergePRdequeuePR→useDequeuePRclosePR→useClosePRreopenPR→useReopenPRdeleteBranch→useDeleteBranchrestoreBranch→useRestoreBranchconvertToDraft→useConvertToDraftmarkReadyForReview→useMarkReadyForReviewupdatePR→useUpdatePRupdateBranch→useUpdateBranchapproveWorkflows→useApproveWorkflowsgetRepoBranches→useRepoBranches(query, not mutation, but currently lives with these)Store fields removed
merging,mergeError,mergeMethod(setter stays —setMergeMethod— sincemergeMethodis a UI selection, not fetched state — reconsider during implementation)dequeueing,closingPR,reopeningPR,deletingBranch,restoringBranchconvertingToDraft,convertingToDraftErrormarkingReady,markingReadyErrorapprovingWorkflows,updatingPRConsumers read
mutation.isPending/mutation.errorinstead.Optimistic + invalidation pattern
Each mutation's
onMutateshould apply the same optimisticsetQueryDatacalls the store used to do inline.onSuccess(oronSettled) invalidates:mergePR→ invalidate PR, timeline, comments, reviews, checks.closePR/reopenPR→ invalidate PR + timeline.deleteBranch/restoreBranch→ invalidate branch status + PR.convertToDraft/markReadyForReview→ invalidate PR + timeline.updatePR→ invalidate PR + timeline.approveWorkflows→ invalidate workflow runs + checks.Consumer changes
pr-overview.tsx,pr-edit-dialog.tsx, and anywhere a merge/close/reopen button lives — swap method calls for mutation.mutate(); swap in-flight flag reads formutation.isPending.Tests
Per mutation hook:
mutation.error.Delete corresponding store mutation-method tests.
Part of #351
Depends on #353.