From b711f7615a13263c2bb7509705f56ea3a61da8c5 Mon Sep 17 00:00:00 2001 From: Brad Harris Date: Wed, 4 Oct 2023 22:41:10 +0000 Subject: [PATCH] adding create project modal --- .../src/components/RepositoryFinder.tsx | 13 +++- .../CreateProjectModal.tsx | 70 +++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 components/dashboard/src/projects/create-project-modal/CreateProjectModal.tsx diff --git a/components/dashboard/src/components/RepositoryFinder.tsx b/components/dashboard/src/components/RepositoryFinder.tsx index 682127c8cd8d2f..5aa65447a9dd68 100644 --- a/components/dashboard/src/components/RepositoryFinder.tsx +++ b/components/dashboard/src/components/RepositoryFinder.tsx @@ -22,7 +22,9 @@ interface RepositoryFinderProps { selectedContextURL?: string; selectedProjectID?: string; maxDisplayItems?: number; - setSelection: (repoUrl: string, projectID?: string) => void; + // TODO: remove setSelection, use onChange + setSelection?: (repoUrl: string, projectID?: string) => void; + onChange?: (repo: SuggestedRepository) => void; onError?: (error: string) => void; disabled?: boolean; } @@ -70,12 +72,17 @@ export default function RepositoryFinder(props: RepositoryFinderProps) { return repo.url === selectedID; }); if (matchingSuggestion) { - props.setSelection(matchingSuggestion.url, matchingSuggestion.projectId); + props.onChange?.(matchingSuggestion); + // TODO: remove this and replace with onChange + props.setSelection?.(matchingSuggestion.url, matchingSuggestion.projectId); return; } // If we have no matching suggestion, it's a context URL they typed/pasted in, so just use that as the url - props.setSelection(selectedID); + props.setSelection?.(selectedID); + props.onChange?.({ + url: selectedID, + }); }, [props, normalizedRepos], ); diff --git a/components/dashboard/src/projects/create-project-modal/CreateProjectModal.tsx b/components/dashboard/src/projects/create-project-modal/CreateProjectModal.tsx new file mode 100644 index 00000000000000..f2fbe36393a9b0 --- /dev/null +++ b/components/dashboard/src/projects/create-project-modal/CreateProjectModal.tsx @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2023 Gitpod GmbH. All rights reserved. + * Licensed under the GNU Affero General Public License (AGPL). + * See License.AGPL.txt in the project root for license information. + */ + +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 RepositoryFinder from "../../components/RepositoryFinder"; +import { useToast } from "../../components/toasts/Toasts"; + +type Props = { + onCreated: (project: Project) => void; + onClose: () => void; +}; + +export const CreateProjectModal: FC = ({ onClose, onCreated }) => { + const [selectedRepo, setSelectedRepo] = useState(); + const createProject = useCreateProject(); + const { toast } = useToast(); + + const handleSubmit = useCallback(() => { + if (!selectedRepo) { + toast("Please select a repository"); + return; + } + + const projectName = selectedRepo?.repositoryName ?? selectedRepo.url; + + const newProjectArgs: CreateProjectArgs = { + name: projectName, + slug: projectName, + cloneUrl: selectedRepo?.url, + // TODO: do we still need this? + appInstallationId: "", + }; + + createProject.mutate(newProjectArgs, { + onSuccess: onCreated, + }); + }, [createProject, onCreated, selectedRepo, toast]); + + return ( + + Create a Project + + + + + {createProject.error.message || "There was a problem creating your project"} + + ) + } + > + + + + + ); +};