Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 9bbdf8c

Browse files
jasonhawkharrisvovakulikov
authored andcommitted
Code Navigation: optimize repo link picker (#58025)
* replace cache-and-network policy with cache-first * add unit test * fix non-site-admin error bug * convert CodeHostType constants to enum
1 parent 666ff03 commit 9bbdf8c

File tree

5 files changed

+127
-22
lines changed

5 files changed

+127
-22
lines changed

client/web/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,6 +1979,7 @@ ts_project(
19791979
"src/repo/linkifiy/get-links.test.ts",
19801980
"src/repo/releases/RepositoryReleasesTagsPage.test.tsx",
19811981
"src/repo/tree/TreePage.test.tsx",
1982+
"src/repo/utils.test.ts",
19821983
"src/search/Notepad.test.tsx",
19831984
"src/search/helpers.test.tsx",
19841985
"src/search/index.test.ts",

client/web/src/repo/RepoLinkPicker.tsx

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,10 @@ import {
3232
useDebounce,
3333
} from '@sourcegraph/wildcard'
3434

35-
import {
36-
ExternalServiceKind,
37-
type RepositoriesSuggestionsResult,
38-
type RepositoriesSuggestionsVariables,
39-
} from '../graphql-operations'
35+
import { type RepositoriesSuggestionsResult, type RepositoriesSuggestionsVariables } from '../graphql-operations'
36+
37+
import { CodeHostType } from './constants'
38+
import { getInitialSearchTerm, stringToCodeHostType } from './utils'
4039

4140
import styles from './RepoLinkPicker.module.scss'
4241

@@ -47,11 +46,11 @@ const REPOSITORIES_QUERY = gql`
4746
id
4847
name
4948
url
50-
externalServices(first: 1) {
51-
nodes {
52-
id
53-
kind
54-
}
49+
# We use externalRepository over externalServices here
50+
# because externalServices is accessible only to admins.
51+
externalRepository {
52+
id
53+
serviceType
5554
}
5655
}
5756
pageInfo {
@@ -85,8 +84,10 @@ export const RepoLinkPicker: FC<RepoLinkPickerProps> = props => {
8584
loading,
8685
} = useQuery<RepositoriesSuggestionsResult, RepositoriesSuggestionsVariables>(REPOSITORIES_QUERY, {
8786
skip: !isSuggestionOpen,
88-
variables: { query: debouncedSearchTerm },
89-
fetchPolicy: 'cache-and-network',
87+
variables: {
88+
query: searchTerm.length === 0 ? getInitialSearchTerm(repositoryName) : debouncedSearchTerm,
89+
},
90+
fetchPolicy: 'cache-first',
9091
})
9192

9293
const handleSelect = (selectedValue: string): void => {
@@ -146,7 +147,9 @@ export const RepoLinkPicker: FC<RepoLinkPickerProps> = props => {
146147
className={styles.item}
147148
>
148149
<Icon
149-
svgPath={getCodeHostIconPath(suggestion.externalServices.nodes[0]?.kind)}
150+
svgPath={getCodeHostIconPath(
151+
stringToCodeHostType(suggestion.externalRepository.serviceType)
152+
)}
150153
height="1rem"
151154
width="1rem"
152155
inline={false}
@@ -165,27 +168,27 @@ export const RepoLinkPicker: FC<RepoLinkPickerProps> = props => {
165168
)
166169
}
167170

168-
export const getCodeHostIconPath = (codeHostType?: ExternalServiceKind): string => {
169-
switch (codeHostType) {
170-
case ExternalServiceKind.GITHUB: {
171+
export const getCodeHostIconPath = (codehost: CodeHostType): string => {
172+
switch (codehost) {
173+
case CodeHostType.GITHUB: {
171174
return mdiGithub
172175
}
173-
case ExternalServiceKind.BITBUCKETCLOUD: {
176+
case CodeHostType.BITBUCKETCLOUD: {
174177
return mdiBitbucket
175178
}
176-
case ExternalServiceKind.BITBUCKETSERVER: {
179+
case CodeHostType.BITBUCKETSERVER: {
177180
return mdiBitbucket
178181
}
179-
case ExternalServiceKind.GITLAB: {
182+
case CodeHostType.GITLAB: {
180183
return mdiGitlab
181184
}
182-
case ExternalServiceKind.GITOLITE: {
185+
case CodeHostType.GITOLITE: {
183186
return mdiGit
184187
}
185-
case ExternalServiceKind.AWSCODECOMMIT: {
188+
case CodeHostType.AWSCODECOMMIT: {
186189
return mdiAws
187190
}
188-
case ExternalServiceKind.AZUREDEVOPS: {
191+
case CodeHostType.AZUREDEVOPS: {
189192
return mdiMicrosoftAzure
190193
}
191194
default: {

client/web/src/repo/constants.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,14 @@ export const LogsPageTabs = {
22
COMMANDS: 0,
33
SYNCLOGS: 1,
44
} as const
5+
6+
export enum CodeHostType {
7+
GITHUB = 'github',
8+
BITBUCKETCLOUD = 'bitbucketCloud',
9+
BITBUCKETSERVER = 'bitbucketServer',
10+
GITLAB = 'gitlab',
11+
GITOLITE = 'gitolite',
12+
AWSCODECOMMIT = 'awsCodeCommit',
13+
AZUREDEVOPS = 'azureDevOps',
14+
OTHER = 'other',
15+
}

client/web/src/repo/utils.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { describe, expect, it } from '@jest/globals'
2+
3+
import { getInitialSearchTerm } from './utils'
4+
5+
describe('getInitialSearchTerm', () => {
6+
const tests: {
7+
name: string
8+
repo: string
9+
expected: string
10+
}[] = [
11+
{
12+
name: 'works with a github repo url',
13+
repo: 'github.com/sourcegraph/sourcegraph',
14+
expected: 'sourcegraph',
15+
},
16+
{
17+
name: 'works with a gitlab repo url',
18+
repo: 'gitlab.com/SourcegraphCody/jsonrpc2',
19+
expected: 'jsonrpc2',
20+
},
21+
{
22+
name: 'works with a perforce depot url',
23+
repo: 'public.perforce.com/sourcegraph/myp4depot',
24+
expected: 'myp4depot',
25+
},
26+
{
27+
name: 'works with a bitbucket repo name',
28+
repo: 'bitbucket.org/username/projectname/mybitbucketrepo',
29+
expected: 'mybitbucketrepo',
30+
},
31+
{
32+
name: 'works with a gerrit repo name',
33+
repo: 'mygerritserver.com/c/mygerritrepo',
34+
expected: 'mygerritrepo',
35+
},
36+
{
37+
name: 'works with an Azure DevOps repo name',
38+
repo: 'https://dev.azure.com/myADOorgname/myADOproject/_git/myADOrepo',
39+
expected: 'myADOrepo',
40+
},
41+
{
42+
name: 'works with a Plastic SCM repo name',
43+
repo: 'https://cloud.plasticscm.com/my-plastic-repo',
44+
expected: 'my-plastic-repo',
45+
},
46+
]
47+
48+
for (const t of tests) {
49+
it(t.name, () => {
50+
expect(getInitialSearchTerm(t.repo)).toBe(t.expected)
51+
})
52+
}
53+
})

client/web/src/repo/utils.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import { at } from 'lodash'
2+
13
import { type GitCommitFields, RepositoryType } from '../graphql-operations'
24

5+
import { CodeHostType } from './constants'
6+
37
export const isPerforceChangelistMappingEnabled = (): boolean =>
48
window.context.experimentalFeatures.perforceChangelistMapping === 'enabled'
59

@@ -12,3 +16,36 @@ export const getCanonicalURL = (sourceType: RepositoryType | string, node: GitCo
1216
isPerforceChangelistMappingEnabled() && isPerforceDepotSource(sourceType) && node.perforceChangelist
1317
? node.perforceChangelist.canonicalURL
1418
: node.canonicalURL
19+
20+
export const getInitialSearchTerm = (repo: string): string => {
21+
const r = repo.split('/')
22+
// This is what the linter required instead of r[r.length - 1].
23+
// *shrugs*
24+
return at(r, r.length - 1)[0]
25+
}
26+
27+
export const stringToCodeHostType = (codeHostType: string): CodeHostType => {
28+
switch (codeHostType) {
29+
case 'github': {
30+
return CodeHostType.GITHUB
31+
}
32+
case 'gitlab': {
33+
return CodeHostType.GITLAB
34+
}
35+
case 'bitbucketCloud': {
36+
return CodeHostType.BITBUCKETCLOUD
37+
}
38+
case 'gitolite': {
39+
return CodeHostType.GITOLITE
40+
}
41+
case 'awsCodeCommit': {
42+
return CodeHostType.AWSCODECOMMIT
43+
}
44+
case 'azureDevOps': {
45+
return CodeHostType.AZUREDEVOPS
46+
}
47+
default: {
48+
return CodeHostType.OTHER
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)