Skip to content

Commit 082022f

Browse files
committed
Refactors pull request searching in Launchpad
Separates search in 3 modes: filtering, url search, & search mode - Introduces dedicated search mode UI with clearer user feedback - Consolidates GitHub/GitLab PR URL parsing into a single utility - Reduces UI flicker during searches with optimistic updates
1 parent 4f18cb2 commit 082022f

File tree

8 files changed

+330
-223
lines changed

8 files changed

+330
-223
lines changed

src/git/models/pullRequest.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import { formatDate, fromNow } from '../../system/date';
77
import { memoize } from '../../system/decorators/memoize';
88
import type { LeftRightCommitCountResult } from '../gitProvider';
99
import type { IssueOrPullRequest, IssueRepository, IssueOrPullRequestState as PullRequestState } from './issue';
10-
import type { PullRequestURLIdentity } from './pullRequest.utils';
10+
import type { PullRequestUrlIdentity } from './pullRequest.utils';
1111
import type { ProviderReference } from './remoteProvider';
1212
import type { Repository } from './repository';
13-
import { createRevisionRange , shortenRevision } from './revision.utils';
13+
import { createRevisionRange, shortenRevision } from './revision.utils';
1414

1515
export type { PullRequestState };
1616

@@ -420,7 +420,7 @@ export async function getOpenedPullRequestRepo(
420420

421421
export function doesPullRequestSatisfyRepositoryURLIdentity(
422422
pr: EnrichablePullRequest | undefined,
423-
{ ownerAndRepo, prNumber }: PullRequestURLIdentity,
423+
{ ownerAndRepo, prNumber }: PullRequestUrlIdentity,
424424
): boolean {
425425
if (pr == null) {
426426
return false;

src/git/models/pullRequest.utils.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
// To avoid this file has been created that can collect more simple functions which
33
// don't require Container and can be tested.
44

5-
export type PullRequestURLIdentity = {
5+
import type { HostingIntegrationId } from '../../constants.integrations';
6+
7+
export interface PullRequestUrlIdentity {
8+
provider?: HostingIntegrationId;
9+
610
ownerAndRepo?: string;
711
prNumber?: string;
8-
};
12+
}
913

10-
export function getPullRequestIdentityValuesFromSearch(search: string): PullRequestURLIdentity {
14+
export function getPullRequestIdentityValuesFromSearch(search: string): PullRequestUrlIdentity {
1115
let ownerAndRepo: string | undefined = undefined;
1216
let prNumber: string | undefined = undefined;
1317

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

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Endpoints } from '@octokit/types';
2+
import { HostingIntegrationId } from '../../../../constants.integrations';
23
import { GitFileIndexStatus } from '../../../../git/models/file';
34
import type { IssueLabel } from '../../../../git/models/issue';
45
import { Issue, RepositoryAccessLevel } from '../../../../git/models/issue';
@@ -10,6 +11,7 @@ import {
1011
PullRequestReviewState,
1112
PullRequestStatusCheckRollupState,
1213
} from '../../../../git/models/pullRequest';
14+
import type { PullRequestUrlIdentity } from '../../../../git/models/pullRequest.utils';
1315
import type { Provider } from '../../../../git/models/remoteProvider';
1416

1517
export interface GitHubBlame {
@@ -509,11 +511,19 @@ export function fromCommitFileStatus(
509511
return undefined;
510512
}
511513

512-
export function isGitHubPullRequestUrl(search: string): boolean {
513-
try {
514-
const url = new URL(search);
515-
return url.host === 'github.com' && url.pathname.includes('/pull/');
516-
} catch {
517-
return false;
518-
}
514+
const prUrlRegex = /^(?:https?:\/\/)?(?:github\.com\/)?([^/]+\/[^/]+)\/pull\/(\d+)/i;
515+
516+
export function isMaybeGitHubPullRequestUrl(url: string): boolean {
517+
if (url == null) return false;
518+
519+
return prUrlRegex.test(url);
520+
}
521+
522+
export function getGitHubPullRequestIdentityFromMaybeUrl(url: string): RequireSome<PullRequestUrlIdentity, 'provider'> {
523+
if (url == null) return { prNumber: undefined, ownerAndRepo: undefined, provider: HostingIntegrationId.GitHub };
524+
525+
const match = prUrlRegex.exec(url);
526+
if (match == null) return { prNumber: undefined, ownerAndRepo: undefined, provider: HostingIntegrationId.GitHub };
527+
528+
return { prNumber: match[2], ownerAndRepo: match[1], provider: HostingIntegrationId.GitHub };
519529
}

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { HostingIntegrationId } from '../../../../constants.integrations';
12
import type { PullRequestState } from '../../../../git/models/pullRequest';
23
import { PullRequest } from '../../../../git/models/pullRequest';
4+
import type { PullRequestUrlIdentity } from '../../../../git/models/pullRequest.utils';
35
import type { Provider } from '../../../../git/models/remoteProvider';
46
import type { Integration } from '../../integration';
57
import type { ProviderPullRequest } from '../models';
@@ -151,11 +153,17 @@ export function fromGitLabMergeRequestProvidersApi(pr: ProviderPullRequest, prov
151153
return fromProviderPullRequest(wrappedPr, provider);
152154
}
153155

154-
export function isGitLabPullRequestUrl(search: string): boolean {
155-
try {
156-
const url = new URL(search);
157-
return url.host === 'gitlab.com' && url.pathname.includes('/merge_requests/');
158-
} catch {
159-
return false;
160-
}
156+
const prUrlRegex = /^(?:https?:\/\/)?(?:gitlab\.com\/)?(.+?)\/-\/merge_requests\/(\d+)/i;
157+
158+
export function isMaybeGitLabPullRequestUrl(url: string): boolean {
159+
return prUrlRegex.test(url);
160+
}
161+
162+
export function getGitLabPullRequestIdentityFromMaybeUrl(url: string): RequireSome<PullRequestUrlIdentity, 'provider'> {
163+
if (url == null) return { prNumber: undefined, ownerAndRepo: undefined, provider: HostingIntegrationId.GitLab };
164+
165+
const match = prUrlRegex.exec(url);
166+
if (match == null) return { prNumber: undefined, ownerAndRepo: undefined, provider: HostingIntegrationId.GitLab };
167+
168+
return { prNumber: match[2], ownerAndRepo: match[1], provider: HostingIntegrationId.GitLab };
161169
}

0 commit comments

Comments
 (0)