@@ -13,6 +13,7 @@ import React, {
1313 useState ,
1414} from 'react' ;
1515import { AutoMerge , QueuedToMerge } from './automergeSelect' ;
16+ import { ContextDropdown } from './contextDropdown' ;
1617import { Dropdown } from './dropdown' ;
1718import { checkIcon , circleFilledIcon , closeIcon , gitMergeIcon , requestChangesIcon , skipIcon , warningIcon } from './icon' ;
1819import { nbsp } from './space' ;
@@ -285,25 +286,47 @@ export const OfferToUpdate = ({ mergeable, isSimple, isCurrentlyCheckedOut, canU
285286
286287export const ReadyForReview = ( { isSimple, isCopilotOnMyBehalf, mergeMethod } : { isSimple : boolean ; isCopilotOnMyBehalf ?: boolean ; mergeMethod : MergeMethod } ) => {
287288 const { readyForReview, readyForReviewAndMerge, updatePR } = useContext ( PullRequestContext ) ;
289+ const [ isBusy , setBusy ] = useState ( false ) ;
288290
289- const submitAction = useCallback ( async ( selected : string ) => {
290- if ( selected === 'readyAndMerge' ) {
291- const result = await readyForReviewAndMerge ( { mergeMethod : mergeMethod } ) ;
292- updatePR ( result ) ;
293- } else {
291+ const markReadyForReview = useCallback ( async ( ) => {
292+ try {
293+ setBusy ( true ) ;
294294 const result = await readyForReview ( ) ;
295295 updatePR ( result ) ;
296+ } finally {
297+ setBusy ( false ) ;
296298 }
297- } , [ readyForReview , readyForReviewAndMerge , updatePR , mergeMethod ] ) ;
299+ } , [ readyForReview , updatePR ] ) ;
298300
299- const options = isCopilotOnMyBehalf
300- ? {
301- ready : 'Ready for Review' ,
302- readyAndMerge : 'Ready, Approve, and Auto-Merge'
301+ const markReadyAndMerge = useCallback ( async ( ) => {
302+ try {
303+ setBusy ( true ) ;
304+ const result = await readyForReviewAndMerge ( { mergeMethod : mergeMethod } ) ;
305+ updatePR ( result ) ;
306+ } finally {
307+ setBusy ( false ) ;
308+ }
309+ } , [ readyForReviewAndMerge , updatePR , mergeMethod ] ) ;
310+
311+ const allOptions = useCallback ( ( ) => {
312+ const actions : { label : string ; value : string ; action : ( event : React . MouseEvent < HTMLButtonElement , MouseEvent > ) => void } [ ] = [
313+ {
314+ label : 'Ready for Review' ,
315+ value : 'ready' ,
316+ action : markReadyForReview
317+ }
318+ ] ;
319+
320+ if ( isCopilotOnMyBehalf ) {
321+ actions . push ( {
322+ label : 'Ready, Approve, and Auto-Merge' ,
323+ value : 'readyAndMerge' ,
324+ action : markReadyAndMerge
325+ } ) ;
303326 }
304- : {
305- ready : 'Ready for Review'
306- } ;
327+
328+ return actions ;
329+ } , [ isCopilotOnMyBehalf , markReadyForReview , markReadyAndMerge ] ) ;
307330
308331 return (
309332 < div className = "ready-for-review-container" >
@@ -315,7 +338,21 @@ export const ReadyForReview = ({ isSimple, isCopilotOnMyBehalf, mergeMethod }: {
315338 </ div >
316339 </ div >
317340 < div className = 'button-container' >
318- < Dropdown options = { options } defaultOption = 'ready' submitAction = { submitAction } />
341+ < ContextDropdown
342+ optionsContext = { ( ) => JSON . stringify ( {
343+ 'preventDefaultContextMenuItems' : true ,
344+ 'github:readyForReviewMenu' : true ,
345+ 'github:readyForReviewMenuWithMerge' : isCopilotOnMyBehalf
346+ } ) }
347+ defaultAction = { markReadyForReview }
348+ defaultOptionLabel = { ( ) => 'Ready for Review' }
349+ defaultOptionValue = { ( ) => 'ready' }
350+ allOptions = { allOptions }
351+ optionsTitle = 'Ready for Review'
352+ disabled = { isBusy }
353+ hasSingleAction = { ! isCopilotOnMyBehalf }
354+ spreadable = { false }
355+ />
319356 </ div >
320357 </ div >
321358 ) ;
0 commit comments