Skip to content

Commit

Permalink
[dashboard] Fix Repository Finder after switch to SCM Service (gitpod…
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexTugarev authored Nov 28, 2023
1 parent 4dfc2b7 commit fa4f79e
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 47 deletions.
43 changes: 21 additions & 22 deletions components/dashboard/src/components/RepositoryFinder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import { FC, useCallback, useMemo, useState } from "react";
import { Combobox, ComboboxElement, ComboboxSelectedItem } from "./podkit/combobox/Combobox";
import RepositorySVG from "../icons/Repository.svg";
import { ReactComponent as RepositoryIcon } from "../icons/RepositoryWithColor.svg";
import { SuggestedRepository } from "@gitpod/gitpod-protocol";
import { MiddleDot } from "./typography/MiddleDot";
import { useUnifiedRepositorySearch } from "../data/git-providers/unified-repositories-search-query";
import { useAuthProviderDescriptions } from "../data/auth-providers/auth-provider-descriptions-query";
import { ReactComponent as Exclamation2 } from "../images/exclamation2.svg";
import { AuthProviderType } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb";
import { SuggestedRepository } from "@gitpod/public-api/lib/gitpod/v1/scm_pb";

interface RepositoryFinderProps {
selectedContextURL?: string;
selectedProjectID?: string;
selectedConfigurationId?: string;
disabled?: boolean;
expanded?: boolean;
excludeProjects?: boolean;
Expand All @@ -26,7 +26,7 @@ interface RepositoryFinderProps {

export default function RepositoryFinder({
selectedContextURL,
selectedProjectID,
selectedConfigurationId: selectedProjectID,
disabled,
expanded,
excludeProjects = false,
Expand All @@ -46,8 +46,8 @@ export default function RepositoryFinder({
(selectedID: string) => {
// selectedId is either projectId or repo url
const matchingSuggestion = repos?.find((repo) => {
if (repo.projectId) {
return repo.projectId === selectedID;
if (repo.configurationId) {
return repo.configurationId === selectedID;
}

return repo.url === selectedID;
Expand All @@ -57,9 +57,11 @@ export default function RepositoryFinder({
return;
}

onChange?.({
url: selectedID,
});
onChange?.(
new SuggestedRepository({
url: selectedID,
}),
);
},
[onChange, repos],
);
Expand All @@ -68,26 +70,23 @@ export default function RepositoryFinder({
const selectedSuggestion = useMemo(() => {
let match = repos?.find((repo) => {
if (selectedProjectID) {
return repo.projectId === selectedProjectID;
return repo.configurationId === selectedProjectID;
}

return repo.url === selectedContextURL;
});

// If no match, it's a context url that was typed/pasted in, so treat it like a suggestion w/ just a url
if (!match && selectedContextURL) {
match = {
match = new SuggestedRepository({
url: selectedContextURL,
};
});
}

// This means we found a matching project, but the context url is different
// user may be using a pr or branch url, so we want to make sure and use that w/ the matching project
if (match && match.projectId && selectedContextURL && match.url !== selectedContextURL) {
match = {
...match,
url: selectedContextURL,
};
if (match && match.configurationId && selectedContextURL && match.url !== selectedContextURL) {
match.url = selectedContextURL;
}

return match;
Expand All @@ -99,7 +98,7 @@ export default function RepositoryFinder({
(searchString: string) => {
const result = repos.map((repo) => {
return {
id: repo.projectId || repo.url,
id: repo.configurationId || repo.url,
element: <SuggestedRepositoryOption repo={repo} />,
isSelectable: true,
} as ComboboxElement;
Expand Down Expand Up @@ -169,15 +168,15 @@ export default function RepositoryFinder({
title={
<div className="truncate">
{displayContextUrl(
selectedSuggestion?.projectName ||
selectedSuggestion?.repositoryName ||
selectedSuggestion?.configurationName ||
selectedSuggestion?.repoName ||
selectedSuggestion?.url,
) || "Select a repository"}
</div>
}
subtitle={
// Only show the url if we have a project or repo name, otherwise it's redundant w/ the title
selectedSuggestion?.projectName || selectedSuggestion?.repositoryName
selectedSuggestion?.configurationName || selectedSuggestion?.repoName
? displayContextUrl(selectedSuggestion?.url)
: undefined
}
Expand All @@ -191,13 +190,13 @@ type SuggestedRepositoryOptionProps = {
repo: SuggestedRepository;
};
const SuggestedRepositoryOption: FC<SuggestedRepositoryOptionProps> = ({ repo }) => {
const name = repo.projectName || repo.repositoryName;
const name = repo.configurationName || repo.repoName;
const repoPath = stripOffProtocol(repo.url);

return (
<div
className="flex flex-row items-center overflow-hidden"
aria-label={`${repo.projectId ? "Project" : "Repo"}: ${repo.url}`}
aria-label={`${repo.configurationId ? "Project" : "Repo"}: ${repo.url}`}
>
<span className={"pr-2"}>
<RepositoryIcon className={`w-5 h-5 text-gray-400`} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
* See License.AGPL.txt in the project root for license information.
*/

import { SuggestedRepository } from "@gitpod/gitpod-protocol";
import { SuggestedRepository } from "@gitpod/public-api/lib/gitpod/v1/scm_pb";
import { deduplicateAndFilterRepositories } from "./unified-repositories-search-query";

function repo(name: string, project?: string): SuggestedRepository {
return {
return new SuggestedRepository({
url: `http://github.com/efu3he4rf/${name}`,
repositoryName: name,
projectName: project,
projectId: project,
};
repoName: name,
configurationName: project,
configurationId: project,
});
}

test("it should deduplicate non-project entries", () => {
const suggestedRepos: SuggestedRepository[] = [repo("foo"), repo("foo2"), repo("foo", "project-foo")];
const deduplicated = deduplicateAndFilterRepositories("foo", false, suggestedRepos);
expect(deduplicated.length).toEqual(2);
expect(deduplicated[1].projectName).toEqual("project-foo");
expect(deduplicated[1].configurationName).toEqual("project-foo");
});

test("it should not deduplicate project entries", () => {
Expand All @@ -41,8 +41,8 @@ test("it should exclude project entries", () => {
];
const deduplicated = deduplicateAndFilterRepositories("foo", true, suggestedRepos);
expect(deduplicated.length).toEqual(2);
expect(deduplicated[0].repositoryName).toEqual("foo");
expect(deduplicated[1].repositoryName).toEqual("foo2");
expect(deduplicated[0].repoName).toEqual("foo");
expect(deduplicated[1].repoName).toEqual("foo2");
});

test("it should match entries in url as well as poject name", () => {
Expand Down Expand Up @@ -72,10 +72,10 @@ test("it keeps the order", () => {
repo("bar", "FOOtest"),
];
const deduplicated = deduplicateAndFilterRepositories("foot", false, suggestedRepos);
expect(deduplicated[0].repositoryName).toEqual("somefOOtest");
expect(deduplicated[1].repositoryName).toEqual("Footest");
expect(deduplicated[2].projectName).toEqual("someFootest");
expect(deduplicated[3].projectName).toEqual("FOOtest");
expect(deduplicated[0].repoName).toEqual("somefOOtest");
expect(deduplicated[1].repoName).toEqual("Footest");
expect(deduplicated[2].configurationName).toEqual("someFootest");
expect(deduplicated[3].configurationName).toEqual("FOOtest");
});

test("it should return all repositories without duplicates when excludeProjects is true", () => {
Expand All @@ -88,6 +88,6 @@ test("it should return all repositories without duplicates when excludeProjects
];
const deduplicated = deduplicateAndFilterRepositories("foo", true, suggestedRepos);
expect(deduplicated.length).toEqual(2);
expect(deduplicated[0].repositoryName).toEqual("foo");
expect(deduplicated[1].repositoryName).toEqual("bar");
expect(deduplicated[0].repoName).toEqual("foo");
expect(deduplicated[1].repoName).toEqual("bar");
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* See License.AGPL.txt in the project root for license information.
*/

import { SuggestedRepository } from "@gitpod/gitpod-protocol";
import { SuggestedRepository } from "@gitpod/public-api/lib/gitpod/v1/scm_pb";
import { useSearchRepositories } from "./search-repositories-query";
import { useSuggestedRepositories } from "./suggested-repositories-query";
import { useMemo } from "react";
Expand Down Expand Up @@ -47,22 +47,22 @@ export function deduplicateAndFilterRepositories(
const reposWithProject = new Set<string>();
if (!excludeProjects) {
suggestedRepos.forEach((r) => {
if (r.projectId) {
if (r.configurationId) {
reposWithProject.add(r.url);
}
});
}
for (const repo of suggestedRepos) {
// filter out project-less entries if an entry with a project exists
if (!repo.projectId && reposWithProject.has(repo.url)) {
if (!repo.configurationId && reposWithProject.has(repo.url)) {
continue;
}
// filter out entries that don't match the search string
if (!`${repo.url}${repo.projectName || ""}`.toLowerCase().includes(normalizedSearchString)) {
if (!`${repo.url}${repo.configurationName || ""}`.toLowerCase().includes(normalizedSearchString)) {
continue;
}
// filter out duplicates
const key = `${repo.url}:${excludeProjects ? "" : repo.projectId || "no-project"}`;
const key = `${repo.url}:${excludeProjects ? "" : repo.configurationId || "no-project"}`;
if (collected.has(key)) {
continue;
}
Expand All @@ -74,7 +74,11 @@ export function deduplicateAndFilterRepositories(
try {
// If the normalizedSearchString is a URL, and it's not present in the proposed results, "artificially" add it here.
new URL(normalizedSearchString);
results.push({ url: normalizedSearchString });
results.push(
new SuggestedRepository({
url: normalizedSearchString,
}),
);
} catch {}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import { FC, useCallback, useState } from "react";
import Modal, { ModalBody, ModalFooter, ModalFooterAlert, ModalHeader } from "../../components/Modal";
import { Button } from "../../components/Button";
import { CreateProjectArgs, useCreateProject } from "../../data/projects/create-project-mutation";
import { Project, SuggestedRepository } from "@gitpod/gitpod-protocol";
import { Project } from "@gitpod/gitpod-protocol";
import RepositoryFinder from "../../components/RepositoryFinder";
import { InputField } from "../../components/forms/InputField";
import { AuthorizeGit, useNeedsGitAuthorization } from "../../components/AuthorizeGit";
import { useTemporaryState } from "../../hooks/use-temporary-value";
import { SuggestedRepository } from "@gitpod/public-api/lib/gitpod/v1/scm_pb";

type Props = {
onCreated: (project: Project) => void;
Expand Down Expand Up @@ -61,7 +62,7 @@ export const CreateProjectModal: FC<Props> = ({ onClose, onCreated }) => {
<InputField label="Repository" className="mb-8 w-full">
<RepositoryFinder
selectedContextURL={selectedRepo?.url}
selectedProjectID={selectedRepo?.projectId}
selectedConfigurationId={selectedRepo?.configurationId}
onChange={setSelectedRepo}
excludeProjects
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const ImportRepositoryModal: FC<Props> = ({ onClose, onCreated }) => {
<InputField className="mb-8 w-full">
<RepositoryFinder
selectedContextURL={selectedRepo?.url}
selectedProjectID={selectedRepo?.projectId}
selectedConfigurationId={selectedRepo?.projectId}
onChange={setSelectedRepo}
excludeProjects
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ export function CreateWorkspacePage() {
<RepositoryFinder
onChange={handleContextURLChange}
selectedContextURL={contextURL}
selectedProjectID={selectedProjectID}
selectedConfigurationId={selectedProjectID}
expanded={!contextURL}
disabled={createWorkspaceMutation.isStarting}
/>
Expand Down

0 comments on commit fa4f79e

Please sign in to comment.