Skip to content

Commit 03229d2

Browse files
committed
Improves draft PR handling and launchpad grouping
Adds action to the launchpad status to open Launchpad to the item
1 parent 509d8f2 commit 03229d2

File tree

7 files changed

+73
-44
lines changed

7 files changed

+73
-44
lines changed

src/plus/integrations/providers/github/github.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ import { PullRequestMergeMethod } from '../../../../git/models/pullRequest';
2525
import type { Provider } from '../../../../git/models/remoteProvider';
2626
import type { RepositoryMetadata } from '../../../../git/models/repositoryMetadata';
2727
import type { GitRevisionRange } from '../../../../git/models/revision';
28-
import { createRevisionRange , getRevisionRangeParts, isRevisionRange, isSha } from '../../../../git/models/revision.utils';
28+
import {
29+
createRevisionRange,
30+
getRevisionRangeParts,
31+
isRevisionRange,
32+
isSha,
33+
} from '../../../../git/models/revision.utils';
2934
import type { GitUser } from '../../../../git/models/user';
3035
import { getGitHubNoReplyAddressParts } from '../../../../git/remotes/github';
3136
import {
@@ -98,6 +103,7 @@ headRepository {
98103
url
99104
}
100105
isCrossRepository
106+
isDraft
101107
mergedAt
102108
permalink
103109
repository {
@@ -122,7 +128,6 @@ assignees(first: 10) {
122128
}
123129
checksUrl
124130
deletions
125-
isDraft
126131
mergeable
127132
mergedBy {
128133
login

src/plus/integrations/providers/github/models.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export interface GitHubPullRequestLite extends Omit<GitHubIssueOrPullRequest, '_
105105
};
106106

107107
isCrossRepository: boolean;
108+
isDraft: boolean;
108109
mergedAt: string | null;
109110
permalink: string;
110111

@@ -152,7 +153,6 @@ export interface GitHubPullRequest extends GitHubPullRequestLite {
152153
};
153154
checksUrl: string;
154155
deletions: number;
155-
isDraft: boolean;
156156
mergeable: GitHubPullRequestMergeableState;
157157
reviewDecision: GitHubPullRequestReviewDecision;
158158
latestReviews: {
@@ -218,6 +218,7 @@ export function fromGitHubPullRequestLite(pr: GitHubPullRequestLite, provider: P
218218
},
219219
isCrossRepository: pr.isCrossRepository,
220220
},
221+
pr.isDraft,
221222
);
222223
}
223224

src/plus/launchpad/launchpad.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ interface GroupedLaunchpadItem extends LaunchpadItem {
131131
}
132132

133133
interface State {
134+
id?: { uuid: string; group: LaunchpadGroup };
134135
item?: GroupedLaunchpadItem;
135136
action?: LaunchpadAction | LaunchpadTargetAction;
136137
initialGroup?: LaunchpadGroup;
@@ -293,6 +294,17 @@ export class LaunchpadCommand extends QuickCommand<State> {
293294
await updateContextItems(this.container, context, { force: newlyConnected });
294295

295296
if (state.counter < 1 || state.item == null) {
297+
if (state.id != null) {
298+
const item = context.result.items?.find(item => item.uuid === state.id?.uuid);
299+
if (item != null) {
300+
state.item = { ...item, group: state.id.group };
301+
if (state.counter < 1) {
302+
state.counter = 1;
303+
}
304+
continue;
305+
}
306+
}
307+
296308
if (this.container.telemetry.enabled) {
297309
this.container.telemetry.sendEvent(
298310
opened ? 'launchpad/steps/main' : 'launchpad/opened',

src/webviews/apps/plus/home/components/branch-card.ts

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { customElement, property, state } from 'lit/decorators.js';
44
import { classMap } from 'lit/directives/class-map.js';
55
import { when } from 'lit/directives/when.js';
66
import type { Commands } from '../../../../../constants.commands';
7-
import type { LaunchpadItem } from '../../../../../plus/launchpad/launchpadProvider';
7+
import type { LaunchpadCommandArgs } from '../../../../../plus/launchpad/launchpad';
88
import {
99
actionGroupMap,
1010
launchpadCategoryToGroupMap,
@@ -422,10 +422,7 @@ export abstract class GlBranchCardBase extends GlElement {
422422
}
423423

424424
get cardIndicator() {
425-
if (this.launchpadItem && this.pr?.state === 'opened') {
426-
return getLaunchpadItemGrouping(this.launchpadItem.category) ?? 'base';
427-
}
428-
return 'base';
425+
return getLaunchpadItemGrouping(getLaunchpadItemGroup(this.pr, this.launchpadItem)) ?? 'base';
429426
}
430427

431428
get branchCardIndicator() {
@@ -715,22 +712,17 @@ export abstract class GlBranchCardBase extends GlElement {
715712
return nothing;
716713
}
717714

718-
let indicator: GlCard['indicator'];
719-
if (this.branch.opened) {
720-
if (this.launchpadItem && this.pr?.state === 'opened') {
721-
indicator = getLaunchpadItemGrouping(this.launchpadItem.category) ?? 'base';
722-
} else {
723-
indicator = 'base';
724-
}
725-
}
715+
const indicator: GlCard['indicator'] = this.branch.opened
716+
? getLaunchpadItemGrouping(getLaunchpadItemGroup(this.pr, this.launchpadItem)) ?? 'base'
717+
: undefined;
726718

727719
const actions = this.renderPrActions();
728720
return html`
729721
<gl-work-item ?expanded=${this.expanded} ?nested=${!this.branch.opened} .indicator=${indicator}>
730722
<div class="branch-item__section">
731723
<p class="branch-item__grouping">
732724
<span class="branch-item__icon">
733-
<pr-icon state=${this.pr.state} pr-id=${this.pr.id}></pr-icon>
725+
<pr-icon ?draft=${this.pr.draft} state=${this.pr.state} pr-id=${this.pr.id}></pr-icon>
734726
</span>
735727
<a href=${this.pr.url} class="branch-item__name branch-item__name--secondary"
736728
>${this.pr.title}</a
@@ -745,47 +737,43 @@ export abstract class GlBranchCardBase extends GlElement {
745737
}
746738

747739
protected renderLaunchpadItem() {
748-
if (this.launchpadItem == null || this.pr?.state !== 'opened') return nothing;
740+
if (this.launchpadItem == null) return nothing;
749741

750-
const group = launchpadCategoryToGroupMap.get(this.launchpadItem.category);
751-
if (group == null || group === 'other' || group === 'draft' || group === 'current-branch') {
752-
return nothing;
753-
}
742+
const group = getLaunchpadItemGroup(this.pr, this.launchpadItem);
743+
if (group == null) return nothing;
754744

755745
const groupLabel = launchpadGroupLabelMap.get(group);
756746
const groupIcon = launchpadGroupIconMap.get(group);
757747

758748
if (groupLabel == null || groupIcon == null) return nothing;
759749
const groupIconString = groupIcon.match(/\$\((.*?)\)/)![1].replace('gitlens', 'gl');
760750

761-
// <a
762-
// href=${createCommandLink<Omit<LaunchpadCommandArgs, 'command'>>('gitlens.showLaunchpad', {
763-
// source: 'home',
764-
// state: {
765-
// item: { ...this.launchpadItem.item, group: group },
766-
// },
767-
// } satisfies Omit<LaunchpadCommandArgs, 'command'>)}
768-
// class="launchpad__grouping"
769-
// >
770-
771751
const tooltip = interpolate(actionGroupMap.get(this.launchpadItem.category)![1], {
772752
author: this.launchpadItem.author?.username ?? 'unknown',
773753
createdDateRelative: fromNow(new Date(this.launchpadItem.createdDate)),
774754
});
775755

776756
return html`<div class="branch-item__section branch-item__section--details" slot="context">
777-
<p class="launchpad-grouping--${getLaunchpadItemGrouping(this.launchpadItem.category)}">
757+
<p class="launchpad-grouping--${getLaunchpadItemGrouping(group)}">
778758
<gl-tooltip content="${tooltip}">
779-
<code-icon icon="${groupIconString}"></code-icon
780-
><span class="branch-item__category">${groupLabel.toUpperCase()}</span>
759+
<a
760+
href=${createCommandLink<Omit<LaunchpadCommandArgs, 'command'>>('gitlens.showLaunchpad', {
761+
source: 'home',
762+
state: {
763+
id: { uuid: this.launchpadItem.uuid, group: group },
764+
},
765+
} satisfies Omit<LaunchpadCommandArgs, 'command'>)}
766+
class="launchpad__grouping"
767+
>
768+
<code-icon icon="${groupIconString}"></code-icon
769+
><span class="branch-item__category">${groupLabel.toUpperCase()}</span></a
770+
>
781771
</gl-tooltip>
782772
</p>
783773
</div>
784774
${groupIconString
785775
? html`<span
786-
class="branch-item__summary launchpad-grouping--${getLaunchpadItemGrouping(
787-
this.launchpadItem.category,
788-
)}"
776+
class="branch-item__summary launchpad-grouping--${getLaunchpadItemGrouping(group)}"
789777
slot="summary"
790778
><gl-tooltip placement="bottom" content="${groupLabel}"
791779
><code-icon icon="${groupIconString}"></code-icon></gl-tooltip
@@ -1031,9 +1019,22 @@ export class GlWorkUnit extends LitElement {
10311019
}
10321020
}
10331021

1034-
function getLaunchpadItemGrouping(category: LaunchpadItem['actionableCategory']) {
1035-
const group = launchpadCategoryToGroupMap.get(category);
1022+
function getLaunchpadItemGroup(
1023+
pr: Awaited<GetOverviewBranch['pr']>,
1024+
launchpadItem: Awaited<NonNullable<Awaited<GetOverviewBranch['pr']>>['launchpad']>,
1025+
) {
1026+
if (launchpadItem == null || pr?.state !== 'opened') return undefined;
1027+
if (pr.draft && launchpadItem.category === 'unassigned-reviewers') return undefined;
1028+
1029+
const group = launchpadCategoryToGroupMap.get(launchpadItem.category);
1030+
if (group == null || group === 'other' || group === 'draft' || group === 'current-branch') {
1031+
return undefined;
1032+
}
1033+
1034+
return group;
1035+
}
10361036

1037+
function getLaunchpadItemGrouping(group: ReturnType<typeof getLaunchpadItemGroup>) {
10371038
switch (group) {
10381039
case 'mergeable':
10391040
return 'mergeable';

src/webviews/apps/shared/components/rich/pr-icon.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ export class PrIcon extends LitElement {
1212
@property()
1313
state?: 'merged' | 'opened' | 'closed' | string;
1414

15+
@property({ type: Boolean })
16+
draft = false;
17+
1518
@property({ attribute: 'pr-id' })
1619
prId?: string;
1720

1821
get icon() {
19-
let prIcon = 'git-pull-request';
22+
let prIcon = this.draft ? 'git-pull-request-draft' : 'git-pull-request';
2023
if (this.state) {
2124
switch (this.state) {
2225
case 'merged':
@@ -31,15 +34,18 @@ export class PrIcon extends LitElement {
3134
}
3235

3336
get classes() {
34-
if (!this.state) return 'pr-icon';
37+
if (!this.state || (this.draft && this.state === 'opened')) {
38+
return 'pr-icon';
39+
}
3540

3641
return `pr-icon pr-icon--${this.state}`;
3742
}
3843

3944
get label() {
40-
if (!this.state) return 'Pull request';
45+
const type = this.draft ? 'Draft pull request' : 'Pull request';
46+
if (!this.state) return type;
4147

42-
return `Pull request ${this.prId ? `#${this.prId}` : ''} is ${this.state}`;
48+
return `${type} ${this.prId ? `#${this.prId}` : ''} is ${this.state}`;
4349
}
4450

4551
override render() {

src/webviews/home/homeWebview.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,7 @@ async function getLaunchpadItemInfo(
14601460
if (lpi == null) return undefined;
14611461

14621462
return {
1463+
uuid: lpi.uuid,
14631464
category: lpi.actionableCategory,
14641465
groups: getLaunchpadItemGroups(lpi),
14651466
suggestedActions: lpi.suggestedActions,
@@ -1498,6 +1499,7 @@ async function getPullRequestInfo(
14981499
url: pr.url,
14991500
state: pr.state,
15001501
title: pr.title,
1502+
draft: pr.isDraft,
15011503
launchpad: getLaunchpadItemInfo(container, pr, launchpadPromise),
15021504
};
15031505
}

src/webviews/home/protocol.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,11 @@ export interface GetOverviewBranch {
147147
title: string;
148148
state: string;
149149
url: string;
150+
draft?: boolean;
150151

151152
launchpad?: Promise<
152153
| {
154+
uuid: string;
153155
category: LaunchpadItem['actionableCategory'];
154156
groups: LaunchpadGroup[];
155157
suggestedActions: LaunchpadItem['suggestedActions'];

0 commit comments

Comments
 (0)