From 5ccdcd3e61cc3d4d3c269c56bb9a20dfdc957c3e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 13:42:28 +0000 Subject: [PATCH 1/3] Initial plan From d73d42de5559de570bfc86baf1fdddcc23b5abb4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 13:54:16 +0000 Subject: [PATCH 2/3] Make Comment the primary action in review dropdown with proper ordering and styling Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --- webviews/components/comment.tsx | 26 +++++++++++++++---------- webviews/components/contextDropdown.tsx | 7 +++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/webviews/components/comment.tsx b/webviews/components/comment.tsx index c83c74bc31..9a1d64f038 100644 --- a/webviews/components/comment.tsx +++ b/webviews/components/comment.tsx @@ -349,8 +349,8 @@ export function AddComment({ isIssue, isAuthor, continueOnGitHub, - currentUserReviewState, - lastReviewType, + currentUserReviewState: _currentUserReviewState, + lastReviewType: _lastReviewType, busy, hasReviewDraft, }: PullRequest) { @@ -372,7 +372,8 @@ export function AddComment({ close(value); }; - let currentSelection: ReviewType = lastReviewType ?? (currentUserReviewState === 'APPROVED' ? ReviewType.Approve : (currentUserReviewState === 'CHANGES_REQUESTED' ? ReviewType.RequestChanges : ReviewType.Comment)); + // Always use Comment as the primary action + let currentSelection: ReviewType = ReviewType.Comment; async function submitAction(action: ReviewType): Promise { const { value } = textareaRef.current!; @@ -460,12 +461,13 @@ export function AddComment({ defaultOptionValue={() => currentSelection} allOptions={() => { const actions: { label: string; value: string; optionDisabled: boolean; action: (event: React.MouseEvent) => void }[] = []; - if (availableActions.approve) { - actions.push({ label: availableActions[ReviewType.Approve]!, value: ReviewType.Approve, action: () => submitAction(ReviewType.Approve), optionDisabled: shouldDisableApproveButton }); - } + // Comment is always the primary action and should appear first if (availableActions.comment) { actions.push({ label: availableActions[ReviewType.Comment]!, value: ReviewType.Comment, action: () => submitAction(ReviewType.Comment), optionDisabled: shouldDisableNonApproveButtons }); } + if (availableActions.approve) { + actions.push({ label: availableActions[ReviewType.Approve]!, value: ReviewType.Approve, action: () => submitAction(ReviewType.Approve), optionDisabled: shouldDisableApproveButton }); + } if (availableActions.requestChanges) { actions.push({ label: availableActions[ReviewType.RequestChanges]!, value: ReviewType.RequestChanges, action: () => submitAction(ReviewType.RequestChanges), optionDisabled: shouldDisableNonApproveButtons }); } @@ -475,6 +477,7 @@ export function AddComment({ disabled={isBusy || busy} hasSingleAction={Object.keys(availableActions).length === 1} spreadable={true} + primaryOptionValue={ReviewType.Comment} /> @@ -532,7 +535,8 @@ export const AddCommentSimple = (pr: PullRequest) => { const { updatePR, requestChanges, approve, submit, openOnGitHub } = useContext(PullRequestContext); const [isBusy, setBusy] = useState(false); const textareaRef = useRef(); - let currentSelection: ReviewType = pr.lastReviewType ?? (pr.currentUserReviewState === 'APPROVED' ? ReviewType.Approve : (pr.currentUserReviewState === 'CHANGES_REQUESTED' ? ReviewType.RequestChanges : ReviewType.Comment)); + // Always use Comment as the primary action + let currentSelection: ReviewType = ReviewType.Comment; async function submitAction(action: ReviewType): Promise { const { value } = textareaRef.current!; @@ -608,12 +612,13 @@ export const AddCommentSimple = (pr: PullRequest) => { defaultOptionValue={() => currentSelection} allOptions={() => { const actions: { label: string; value: string; optionDisabled: boolean; action: (event: React.MouseEvent) => void }[] = []; - if (availableActions.approve) { - actions.push({ label: availableActions[ReviewType.Approve]!, value: ReviewType.Approve, action: () => submitAction(ReviewType.Approve), optionDisabled: shouldDisableApproveButton }); - } + // Comment is always the primary action and should appear first if (availableActions.comment) { actions.push({ label: availableActions[ReviewType.Comment]!, value: ReviewType.Comment, action: () => submitAction(ReviewType.Comment), optionDisabled: shouldDisableNonApproveButtons }); } + if (availableActions.approve) { + actions.push({ label: availableActions[ReviewType.Approve]!, value: ReviewType.Approve, action: () => submitAction(ReviewType.Approve), optionDisabled: shouldDisableApproveButton }); + } if (availableActions.requestChanges) { actions.push({ label: availableActions[ReviewType.RequestChanges]!, value: ReviewType.RequestChanges, action: () => submitAction(ReviewType.RequestChanges), optionDisabled: shouldDisableNonApproveButtons }); } @@ -623,6 +628,7 @@ export const AddCommentSimple = (pr: PullRequest) => { disabled={isBusy || pr.busy} hasSingleAction={Object.keys(availableActions).length === 1} spreadable={true} + primaryOptionValue={ReviewType.Comment} /> diff --git a/webviews/components/contextDropdown.tsx b/webviews/components/contextDropdown.tsx index 9863dbb203..907777903d 100644 --- a/webviews/components/contextDropdown.tsx +++ b/webviews/components/contextDropdown.tsx @@ -17,6 +17,7 @@ interface ContextDropdownProps { hasSingleAction?: boolean; spreadable: boolean; isSecondary?: boolean; + primaryOptionValue?: string; } function useWindowSize() { @@ -32,7 +33,7 @@ function useWindowSize() { return size; } -export const ContextDropdown = ({ optionsContext, defaultOptionLabel, defaultOptionValue, defaultAction, allOptions: options, optionsTitle, disabled, hasSingleAction, spreadable, isSecondary }: ContextDropdownProps) => { +export const ContextDropdown = ({ optionsContext, defaultOptionLabel, defaultOptionValue, defaultAction, allOptions: options, optionsTitle, disabled, hasSingleAction, spreadable, isSecondary, primaryOptionValue }: ContextDropdownProps) => { const [expanded, setExpanded] = useState(false); const onHideAction = (e: MouseEvent | KeyboardEvent) => { if (e.target instanceof HTMLElement && e.target.classList.contains('split-right')) { @@ -56,7 +57,9 @@ export const ContextDropdown = ({ optionsContext, defaultOptionLabel, defaultOpt return
{divRef.current && spreadable && (divRef.current.clientWidth > 375) && options && !hasSingleAction ? options().map(({ label, value, action, optionDisabled }) => { - return ; + // Only the primary option should use the primary (blue) button style when expanded + const isPrimary = primaryOptionValue && value === primaryOptionValue; + return ; }) :
From 2554aa276c746b0e7026cf6f6c7bdea06617ec61 Mon Sep 17 00:00:00 2001 From: Alex Ross <38270282+alexr00@users.noreply.github.com> Date: Wed, 12 Nov 2025 15:50:16 +0100 Subject: [PATCH 3/3] clean up --- package.json | 26 ++++++++++++++++---------- webviews/components/comment.tsx | 12 ++++-------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 442a0f740b..353e54de7b 100644 --- a/package.json +++ b/package.json @@ -3480,16 +3480,19 @@ "group": "1_create@2" }, { - "command": "review.approve", - "when": "webviewId == 'github:activePullRequest' && github:reviewCommentMenu && github:reviewCommentApprove" + "command": "review.comment", + "when": "webviewId == 'github:activePullRequest' && github:reviewCommentMenu && github:reviewCommentComment", + "group": "1_review@1" }, { - "command": "review.comment", - "when": "webviewId == 'github:activePullRequest' && github:reviewCommentMenu && github:reviewCommentComment" + "command": "review.approve", + "when": "webviewId == 'github:activePullRequest' && github:reviewCommentMenu && github:reviewCommentApprove", + "group": "1_review@2" }, { "command": "review.requestChanges", - "when": "webviewId == 'github:activePullRequest' && github:reviewCommentMenu && github:reviewCommentRequestChanges" + "when": "webviewId == 'github:activePullRequest' && github:reviewCommentMenu && github:reviewCommentRequestChanges", + "group": "1_review@3" }, { "command": "review.approveOnDotCom", @@ -3500,16 +3503,19 @@ "when": "webviewId == 'github:activePullRequest' && github:reviewCommentMenu && github:reviewCommentRequestChangesOnDotCom" }, { - "command": "review.approveDescription", - "when": "webviewId == PullRequestOverview && github:reviewCommentMenu && github:reviewCommentApprove" + "command": "review.commentDescription", + "when": "webviewId == PullRequestOverview && github:reviewCommentMenu && github:reviewCommentComment", + "group": "1_review@1" }, { - "command": "review.commentDescription", - "when": "webviewId == PullRequestOverview && github:reviewCommentMenu && github:reviewCommentComment" + "command": "review.approveDescription", + "when": "webviewId == PullRequestOverview && github:reviewCommentMenu && github:reviewCommentApprove", + "group": "1_review@2" }, { "command": "review.requestChangesDescription", - "when": "webviewId == PullRequestOverview && github:reviewCommentMenu && github:reviewCommentRequestChanges" + "when": "webviewId == PullRequestOverview && github:reviewCommentMenu && github:reviewCommentRequestChanges", + "group": "1_review@3" }, { "command": "review.approveOnDotComDescription", diff --git a/webviews/components/comment.tsx b/webviews/components/comment.tsx index 9a1d64f038..bfd5e63286 100644 --- a/webviews/components/comment.tsx +++ b/webviews/components/comment.tsx @@ -349,8 +349,8 @@ export function AddComment({ isIssue, isAuthor, continueOnGitHub, - currentUserReviewState: _currentUserReviewState, - lastReviewType: _lastReviewType, + currentUserReviewState, + lastReviewType, busy, hasReviewDraft, }: PullRequest) { @@ -372,8 +372,7 @@ export function AddComment({ close(value); }; - // Always use Comment as the primary action - let currentSelection: ReviewType = ReviewType.Comment; + let currentSelection: ReviewType = lastReviewType ?? (currentUserReviewState === 'APPROVED' ? ReviewType.Approve : (currentUserReviewState === 'CHANGES_REQUESTED' ? ReviewType.RequestChanges : ReviewType.Comment)); async function submitAction(action: ReviewType): Promise { const { value } = textareaRef.current!; @@ -461,7 +460,6 @@ export function AddComment({ defaultOptionValue={() => currentSelection} allOptions={() => { const actions: { label: string; value: string; optionDisabled: boolean; action: (event: React.MouseEvent) => void }[] = []; - // Comment is always the primary action and should appear first if (availableActions.comment) { actions.push({ label: availableActions[ReviewType.Comment]!, value: ReviewType.Comment, action: () => submitAction(ReviewType.Comment), optionDisabled: shouldDisableNonApproveButtons }); } @@ -535,8 +533,7 @@ export const AddCommentSimple = (pr: PullRequest) => { const { updatePR, requestChanges, approve, submit, openOnGitHub } = useContext(PullRequestContext); const [isBusy, setBusy] = useState(false); const textareaRef = useRef(); - // Always use Comment as the primary action - let currentSelection: ReviewType = ReviewType.Comment; + let currentSelection: ReviewType = pr.lastReviewType ?? (pr.currentUserReviewState === 'APPROVED' ? ReviewType.Approve : (pr.currentUserReviewState === 'CHANGES_REQUESTED' ? ReviewType.RequestChanges : ReviewType.Comment)); async function submitAction(action: ReviewType): Promise { const { value } = textareaRef.current!; @@ -612,7 +609,6 @@ export const AddCommentSimple = (pr: PullRequest) => { defaultOptionValue={() => currentSelection} allOptions={() => { const actions: { label: string; value: string; optionDisabled: boolean; action: (event: React.MouseEvent) => void }[] = []; - // Comment is always the primary action and should appear first if (availableActions.comment) { actions.push({ label: availableActions[ReviewType.Comment]!, value: ReviewType.Comment, action: () => submitAction(ReviewType.Comment), optionDisabled: shouldDisableNonApproveButtons }); }