diff --git a/ui/src/components/NewProjectDialog.tsx b/ui/src/components/NewProjectDialog.tsx index 6378dfda..6a449b52 100644 --- a/ui/src/components/NewProjectDialog.tsx +++ b/ui/src/components/NewProjectDialog.tsx @@ -23,10 +23,13 @@ import { Calendar, Plus, X, - FolderOpen, - Github, - GitBranch, + HelpCircle, } from "lucide-react"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { PROJECT_COLORS } from "@paperclipai/shared"; import { cn } from "../lib/utils"; import { MarkdownEditor, type MarkdownEditorRef } from "./MarkdownEditor"; @@ -41,8 +44,6 @@ const projectStatuses = [ { value: "cancelled", label: "Cancelled" }, ]; -type WorkspaceSetup = "none" | "local" | "repo" | "both"; - export function NewProjectDialog() { const { newProjectOpen, closeNewProject } = useDialog(); const { selectedCompanyId, selectedCompany } = useCompany(); @@ -53,7 +54,6 @@ export function NewProjectDialog() { const [goalIds, setGoalIds] = useState([]); const [targetDate, setTargetDate] = useState(""); const [expanded, setExpanded] = useState(false); - const [workspaceSetup, setWorkspaceSetup] = useState("none"); const [workspaceLocalPath, setWorkspaceLocalPath] = useState(""); const [workspaceRepoUrl, setWorkspaceRepoUrl] = useState(""); const [workspaceError, setWorkspaceError] = useState(null); @@ -87,7 +87,6 @@ export function NewProjectDialog() { setGoalIds([]); setTargetDate(""); setExpanded(false); - setWorkspaceSetup("none"); setWorkspaceLocalPath(""); setWorkspaceRepoUrl(""); setWorkspaceError(null); @@ -124,23 +123,16 @@ export function NewProjectDialog() { } }; - const toggleWorkspaceSetup = (next: WorkspaceSetup) => { - setWorkspaceSetup((prev) => (prev === next ? "none" : next)); - setWorkspaceError(null); - }; - async function handleSubmit() { if (!selectedCompanyId || !name.trim()) return; - const localRequired = workspaceSetup === "local" || workspaceSetup === "both"; - const repoRequired = workspaceSetup === "repo" || workspaceSetup === "both"; const localPath = workspaceLocalPath.trim(); const repoUrl = workspaceRepoUrl.trim(); - if (localRequired && !isAbsolutePath(localPath)) { + if (localPath && !isAbsolutePath(localPath)) { setWorkspaceError("Local folder must be a full absolute path."); return; } - if (repoRequired && !isGitHubRepoUrl(repoUrl)) { + if (repoUrl && !isGitHubRepoUrl(repoUrl)) { setWorkspaceError("Repo must use a valid GitHub repo URL."); return; } @@ -157,28 +149,15 @@ export function NewProjectDialog() { ...(targetDate ? { targetDate } : {}), }); - const workspacePayloads: Array> = []; - if (localRequired && repoRequired) { - workspacePayloads.push({ - name: deriveWorkspaceNameFromPath(localPath), - cwd: localPath, - repoUrl, - }); - } else if (localRequired) { - workspacePayloads.push({ - name: deriveWorkspaceNameFromPath(localPath), - cwd: localPath, - }); - } else if (repoRequired) { - workspacePayloads.push({ - name: deriveWorkspaceNameFromRepo(repoUrl), - repoUrl, - }); - } - for (const workspacePayload of workspacePayloads) { - await projectsApi.createWorkspace(created.id, { - ...workspacePayload, - }); + if (localPath || repoUrl) { + const workspacePayload: Record = { + name: localPath + ? deriveWorkspaceNameFromPath(localPath) + : deriveWorkspaceNameFromRepo(repoUrl), + ...(localPath ? { cwd: localPath } : {}), + ...(repoUrl ? { repoUrl } : {}), + }; + await projectsApi.createWorkspace(created.id, workspacePayload); } queryClient.invalidateQueries({ queryKey: queryKeys.projects.list(selectedCompanyId) }); @@ -280,80 +259,51 @@ export function NewProjectDialog() {
-
-

Where will work be done on this project?

-

Add a repo and/or local folder for this project.

-
-
- - - +
+
+ + optional + + + + + + Link a GitHub repository so agents can clone, read, and push code for this project. + + +
+ { setWorkspaceRepoUrl(e.target.value); setWorkspaceError(null); }} + placeholder="https://github.com/org/repo" + />
- {(workspaceSetup === "local" || workspaceSetup === "both") && ( -
- -
- setWorkspaceLocalPath(e.target.value)} - placeholder="/absolute/path/to/workspace" - /> - -
+
+
+ + optional + + + + + + Set an absolute path on this machine where local agents will read and write files for this project. + +
- )} - {(workspaceSetup === "repo" || workspaceSetup === "both") && ( -
- +
setWorkspaceRepoUrl(e.target.value)} - placeholder="https://github.com/org/repo" + className="w-full rounded border border-border bg-transparent px-2 py-1 text-xs font-mono outline-none" + value={workspaceLocalPath} + onChange={(e) => { setWorkspaceLocalPath(e.target.value); setWorkspaceError(null); }} + placeholder="/absolute/path/to/workspace" /> +
- )} +
+ {workspaceError && (

{workspaceError}

)}