11import { css , html , LitElement , nothing } from 'lit' ;
22import { customElement , property } from 'lit/decorators.js' ;
33import { when } from 'lit/directives/when.js' ;
4+ import type { Commands } from '../../../../../constants.commands' ;
45import type { GitTrackingState } from '../../../../../git/models/branch' ;
56import type { GetOverviewBranch } from '../../../../home/protocol' ;
67import '../../../shared/components/code-icon' ;
@@ -11,6 +12,8 @@ import '../../../shared/components/commit/commit-stats';
1112import '../../../shared/components/formatted-date' ;
1213import '../../../shared/components/pills/tracking' ;
1314import '../../../shared/components/rich/pr-icon' ;
15+ import '../../../shared/components/actions/action-item' ;
16+ import '../../../shared/components/actions/action-nav' ;
1417
1518type OverviewBranch = GetOverviewBranch ;
1619
@@ -54,14 +57,17 @@ export class GlSection extends LitElement {
5457@customElement ( 'gl-branch-section' )
5558export class GlBranchSection extends LitElement {
5659 @property ( { type : String } ) label ! : string ;
60+ @property ( ) repo ! : string ;
5761 @property ( { type : Array } ) branches ! : GetOverviewBranch [ ] ;
5862
5963 override render ( ) {
6064 return html `
6165 < gl-section >
6266 < span slot ="heading "> ${ this . label } </ span >
6367 < span slot ="heading-actions "> < slot name ="heading-actions "> </ slot > </ span >
64- ${ this . branches . map ( branch => html `< gl-branch-card .branch =${ branch } > </ gl-branch-card > ` ) }
68+ ${ this . branches . map (
69+ branch => html `< gl-branch-card .repo =${ this . repo } .branch =${ branch } > </ gl-branch-card > ` ,
70+ ) }
6571 </ gl-section >
6672 ` ;
6773 }
@@ -80,13 +86,16 @@ export const branchCardStyles = css`
8086 /* background-color: var(--vscode-gitDecoration-untrackedResourceForeground); */
8187 }
8288
83- /* .branch-item {} */
89+ .branch-item {
90+ position: relative;
91+ }
8492
8593 .branch-item__main {
8694 display: flex;
8795 /* flex-direction: column; */
8896 /* align-items: center; */
8997 gap: 0.4rem;
98+ margin-block-end: 0;
9099 }
91100
92101 .branch-item__icon {
@@ -118,6 +127,7 @@ export const branchCardStyles = css`
118127 /* align-items: center; */
119128 font-size: 0.9em;
120129 color: var(--vscode-descriptionForeground);
130+ margin-block-end: 0;
121131 }
122132 .branch-item__details > * {
123133 margin-block: 0;
@@ -165,15 +175,37 @@ export const branchCardStyles = css`
165175 overflow: hidden;
166176 margin-inline-start: auto;
167177 }
178+
179+ .branch-item__actions {
180+ position: absolute;
181+ right: 0.4rem;
182+ bottom: 0.4rem;
183+ padding: 0.2rem 0.4rem;
184+ background-color: var(--gl-card-background);
185+ }
186+
187+ .branch-item:not(:focus-within):not(:hover) .branch-item__actions {
188+ display: none;
189+ }
168190` ;
169191
170192@customElement ( 'gl-branch-card' )
171193export class GlBranchCard extends LitElement {
172194 static override styles = branchCardStyles ;
173195
196+ @property ( )
197+ repo ! : string ;
198+
174199 @property ( { type : Object } )
175200 branch ! : GetOverviewBranch ;
176201
202+ get branchRefs ( ) {
203+ return {
204+ repoPath : this . repo ,
205+ branchId : this . branch . id ,
206+ } ;
207+ }
208+
177209 override render ( ) {
178210 const { name, pr, opened : active , timestamp : date , state, workingTreeState } = this . branch ;
179211 return html `
@@ -207,6 +239,7 @@ export class GlBranchCard extends LitElement {
207239 html `< formatted-date .date =${ new Date ( date ! ) } class ="branch-item__date"> </ formatted-date > ` ,
208240 ) }
209241 </ div >
242+ ${ this . renderActions ( ) }
210243 </ gl-card >
211244 ` ;
212245 }
@@ -291,4 +324,73 @@ export class GlBranchCard extends LitElement {
291324
292325 return nothing ;
293326 }
327+
328+ private renderActions ( ) {
329+ const actions = [ ] ;
330+ if ( this . branch . pr ) {
331+ actions . push (
332+ html `< action-item
333+ label ="Open Pull Request Changes "
334+ icon ="request-changes "
335+ href =${ this . createCommandLink ( 'gitlens.home.openPullRequestComparison' ) }
336+ > </ action-item > ` ,
337+ ) ;
338+ actions . push (
339+ html `< action-item
340+ label ="Open Pull Request on Remote "
341+ icon ="globe "
342+ href =${ this . createCommandLink ( 'gitlens.home.openPullRequestOnRemote' ) }
343+ > </ action-item > ` ,
344+ ) ;
345+ } else {
346+ actions . push (
347+ html `< action-item
348+ label ="Create Pull Request... "
349+ icon ="git-pull-request-create "
350+ href =${ this . createCommandLink ( 'gitlens.home.createPullRequest' ) }
351+ > </ action-item > ` ,
352+ ) ;
353+ }
354+ if ( this . branch . worktree ) {
355+ actions . push (
356+ html `< action-item
357+ label ="Open Worktree "
358+ icon ="browser "
359+ href =${ this . createCommandLink ( 'gitlens.home.openWorktree' ) }
360+ > </ action-item > ` ,
361+ ) ;
362+ } else {
363+ actions . push (
364+ html `< action-item
365+ label ="Switch to Branch... "
366+ icon ="gl-switch "
367+ href =${ this . createCommandLink ( 'gitlens.home.switchToBranch' ) }
368+ > </ action-item > ` ,
369+ ) ;
370+ }
371+
372+ // branch actions
373+ actions . push (
374+ html `< action-item
375+ label ="Fetch "
376+ icon ="gl-repo-fetch "
377+ href =${ this . createCommandLink ( 'gitlens.home.fetch' ) }
378+ > </ action-item > ` ,
379+ ) ;
380+
381+ if ( ! actions . length ) {
382+ return nothing ;
383+ }
384+ return html `< action-nav class ="branch-item__actions "> ${ actions } </ action-nav > ` ;
385+ }
386+
387+ private createCommandLink ( command : string ) {
388+ return createCommandLink ( command , this . branchRefs ) ;
389+ }
390+ }
391+
392+ export function createCommandLink < T > ( command : Commands | string , args : T ) {
393+ if ( args == null ) return `command:${ command } ` ;
394+
395+ return `command:${ command } ?${ encodeURIComponent ( typeof args === 'string' ? args : JSON . stringify ( args ) ) } ` ;
294396}
0 commit comments