Skip to content

feat(app): add Copy PR URL to checkout dropdown#1656

Open
thgcst wants to merge 2 commits into
getpaseo:mainfrom
thgcst:feat/copy-pr-url
Open

feat(app): add Copy PR URL to checkout dropdown#1656
thgcst wants to merge 2 commits into
getpaseo:mainfrom
thgcst:feat/copy-pr-url

Conversation

@thgcst

@thgcst thgcst commented Jun 22, 2026

Copy link
Copy Markdown

Closes #1655

What changed

Added a Copy PR URL item to the git actions dropdown, positioned immediately after View PR.

  • Tapping it copies the PR URL to the clipboard
  • Shows a "URL copied" success toast
  • Dropdown closes immediately on select
  • Only visible when a PR exists for the current branch

Testing

Tested on desktop web with a branch that has an open PR:

  • "Copy PR URL" appears right below "View PR" in the dropdown
  • Tapping it closes the dropdown and shows the success toast
  • Pasting confirms the correct PR URL was copied

Platforms tested

  • Desktop (web/Electron)

I only tested on desktop. I don't have a native device setup to test iOS/Android, but the change uses expo-clipboard (Clipboard.setStringAsync) which is the same cross-platform utility already used elsewhere in the app.

Adds a "Copy PR URL" item to the git actions dropdown, positioned
immediately after "View PR". Tapping it copies the PR URL to the
clipboard and shows a "URL copied" success toast. The dropdown closes
on select.

Closes getpaseo#1655
@thgcst

thgcst commented Jun 22, 2026

Copy link
Copy Markdown
Author
Captura de Tela 2026-06-21 às 23 27 45 Captura de Tela 2026-06-21 às 23 30 19

@greptile-apps

greptile-apps Bot commented Jun 22, 2026

Copy link
Copy Markdown

Greptile Summary

Adds a Copy PR URL entry to the git actions dropdown, placed immediately after View PR. The action is only surfaced when a PR exists (hasPullRequest && pullRequestUrl), closes the dropdown on tap, and shows a success/error toast after the async clipboard write resolves.

  • policy.ts conditionally builds the action and inserts it into the secondary ID list right after the pr action in the getFeatureActionIds loop; use-actions.tsx wires the handleCopyPrUrl callback with correct .then()/.catch() async handling.
  • Icons, i18n strings (6 locales), and test fixture are all updated to keep the system consistent with the new action ID.

Confidence Score: 5/5

The change is additive and self-contained — no existing action behaviour is altered, and the async clipboard/toast path handles both success and failure correctly.

The new action is gated by the same hasPullRequest && pullRequestUrl condition everywhere it is built, inserted, and rendered, so no runtime inconsistency exists. The async handler properly chains .then()/.catch() so the success toast is only shown after the clipboard write resolves.

No files require special attention. The only note is that actions-split-button.tsx accumulates per-action-ID closeOnSelect exceptions inline rather than on the action interface itself.

Important Files Changed

Filename Overview
packages/app/src/git/policy.ts Adds copy-pr-url to GitActionId, builds the action conditionally when hasPullRequest && pullRequestUrl, and inserts it into secondaryIds immediately after pr in the feature action loop. Logic is sound; both guards use the same condition.
packages/app/src/git/use-actions.tsx Adds handleCopyPrUrl callback with proper async .then()/.catch() chaining, wires it into the buildGitActions runtime, and handles the translation case. Async error handling is correct — success toast is shown in .then(), not synchronously.
packages/app/src/git/actions-split-button.tsx Extends closeOnSelect to also match copy-pr-url so the dropdown closes on tap, following the same existing pattern used for the pr action.
packages/app/src/git/diff-pane.tsx Adds Copy icon via withUnistyles and wires it into the icons object passed to useGitActions, consistent with how every other action icon is added.
packages/app/src/git/workspace-actions.tsx Mirrors the icon wiring in diff-pane.tsx for the workspace panel, adding ThemedCopy and copyPrUrl to the static ICONS map.
packages/app/src/git/policy.test.ts Adds copy-pr-url to the fixture to satisfy the exhaustive Record<GitActionId, …> type. No new behavioral assertions are added for the action's visibility or ordering.
packages/app/src/i18n/resources/en.ts Adds copyPrUrl, copyPrUrlSuccess, and failedCopyPrUrl keys; same additions mirrored across all six locale files.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant SplitButton as GitActionsSplitButton
    participant useActions as useGitActions
    participant Policy as buildGitActions (policy.ts)
    participant Clipboard as expo-clipboard
    participant Toast

    User->>SplitButton: opens dropdown
    SplitButton->>useActions: gitActions.secondary
    useActions->>Policy: buildGitActions(input)
    Note over Policy: hasPullRequest && pullRequestUrl?<br/>→ add copy-pr-url to allActions<br/>→ insert after "pr" in secondaryIds
    Policy-->>useActions: "GitActions { secondary: [..., pr, copy-pr-url, ...] }"
    useActions-->>SplitButton: secondary list rendered
    User->>SplitButton: taps "Copy PR URL"
    Note over SplitButton: closeOnSelect=true (id=copy-pr-url)<br/>→ dropdown closes immediately
    SplitButton->>useActions: handleCopyPrUrl()
    useActions->>Clipboard: copyToClipboard(prStatus.url)
    alt success
        Clipboard-->>useActions: resolved
        useActions->>Toast: show("URL copied", success)
    else failure
        Clipboard-->>useActions: rejected
        useActions->>Toast: show("Failed to copy PR URL", error)
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant SplitButton as GitActionsSplitButton
    participant useActions as useGitActions
    participant Policy as buildGitActions (policy.ts)
    participant Clipboard as expo-clipboard
    participant Toast

    User->>SplitButton: opens dropdown
    SplitButton->>useActions: gitActions.secondary
    useActions->>Policy: buildGitActions(input)
    Note over Policy: hasPullRequest && pullRequestUrl?<br/>→ add copy-pr-url to allActions<br/>→ insert after "pr" in secondaryIds
    Policy-->>useActions: "GitActions { secondary: [..., pr, copy-pr-url, ...] }"
    useActions-->>SplitButton: secondary list rendered
    User->>SplitButton: taps "Copy PR URL"
    Note over SplitButton: closeOnSelect=true (id=copy-pr-url)<br/>→ dropdown closes immediately
    SplitButton->>useActions: handleCopyPrUrl()
    useActions->>Clipboard: copyToClipboard(prStatus.url)
    alt success
        Clipboard-->>useActions: resolved
        useActions->>Toast: show("URL copied", success)
    else failure
        Clipboard-->>useActions: rejected
        useActions->>Toast: show("Failed to copy PR URL", error)
    end
Loading

Reviews (2): Last reviewed commit: "fix(app): show error toast on clipboard ..." | Re-trigger Greptile

Comment thread packages/app/src/git/use-actions.tsx Outdated
Comment on lines +130 to +134
"copy-pr-url": {
disabled: false,
status: "idle",
handler: () => undefined,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 No test assertions for the new action's ordering or visibility

The only change here is adding copy-pr-url to the fixture, which is required to keep existing tests compiling. There are no new test cases verifying that copy-pr-url appears immediately after pr in the secondary list, that it is absent when hasPullRequest is false, or that it is absent when pullRequestUrl is null. Given the injection logic lives in a for-loop inside buildGitActions, a policy test covering these three cases would be the natural place to pin the behavior.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Copy PR URL from checkout actions dropdown

2 participants