fix(ui): project dialog improvements, onboarding cleanup, scroll-area fix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dotta
2026-03-02 16:09:07 -06:00
parent f12bef2f77
commit 7642743e62
4 changed files with 23 additions and 52 deletions

View File

@@ -31,6 +31,7 @@ import { PROJECT_COLORS } from "@paperclip/shared";
import { cn } from "../lib/utils";
import { MarkdownEditor, type MarkdownEditorRef } from "./MarkdownEditor";
import { StatusBadge } from "./StatusBadge";
import { ChoosePathButton } from "./PathInstructionsModal";
const projectStatuses = [
{ value: "backlog", label: "Backlog" },
@@ -333,12 +334,15 @@ export function NewProjectDialog() {
{(workspaceSetup === "local" || workspaceSetup === "both") && (
<div className="rounded-md border border-border p-2">
<label className="mb-1 block text-xs text-muted-foreground">Local folder (full path)</label>
<input
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)}
placeholder="/absolute/path/to/workspace"
/>
<div className="flex items-center gap-2">
<input
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)}
placeholder="/absolute/path/to/workspace"
/>
<ChoosePathButton />
</div>
</div>
)}
{(workspaceSetup === "repo" || workspaceSetup === "both") && (

View File

@@ -19,6 +19,7 @@ import { cn } from "../lib/utils";
import { getUIAdapter } from "../adapters";
import { defaultCreateValues } from "./agent-config-defaults";
import { AsciiArtAnimation } from "./AsciiArtAnimation";
import { ChoosePathButton } from "./PathInstructionsModal";
import {
Building2,
Bot,
@@ -63,7 +64,6 @@ export function OnboardingWizard() {
const [command, setCommand] = useState("");
const [args, setArgs] = useState("");
const [url, setUrl] = useState("");
const [cwdPickerNotice, setCwdPickerNotice] = useState<string | null>(null);
// Step 3
const [taskTitle, setTaskTitle] = useState("Create your CEO HEARTBEAT.md");
@@ -94,7 +94,6 @@ export function OnboardingWizard() {
setCommand("");
setArgs("");
setUrl("");
setCwdPickerNotice(null);
setTaskTitle("Create your CEO HEARTBEAT.md");
setTaskDescription("You're the CEO of the company, make sure you have a file agents/ceo/HEARTBEAT.md that tells you your core loop. You MUST use the Paperclip SKILL.");
setCreatedCompanyId(null);
@@ -415,44 +414,8 @@ export function OnboardingWizard() {
value={cwd}
onChange={(e) => setCwd(e.target.value)}
/>
<button
type="button"
className="inline-flex items-center rounded-md border border-border px-2 py-0.5 text-xs text-muted-foreground hover:bg-accent/50 transition-colors shrink-0"
onClick={async () => {
try {
setCwdPickerNotice(null);
// @ts-expect-error -- showDirectoryPicker is not in all TS lib defs yet
const handle = await window.showDirectoryPicker({ mode: "read" });
const pickedPath =
typeof handle === "object" &&
handle !== null &&
typeof (handle as { path?: unknown }).path === "string"
? String((handle as { path: string }).path)
: "";
if (pickedPath) {
setCwd(pickedPath);
return;
}
const selectedName =
typeof handle === "object" &&
handle !== null &&
typeof (handle as { name?: unknown }).name === "string"
? String((handle as { name: string }).name)
: "selected folder";
setCwdPickerNotice(
`Directory picker only exposed "${selectedName}". Paste the absolute path manually.`,
);
} catch {
// user cancelled or API unsupported
}
}}
>
Choose
</button>
<ChoosePathButton />
</div>
{cwdPickerNotice && (
<p className="mt-1 text-xs text-amber-400">{cwdPickerNotice}</p>
)}
</div>
<div>
<label className="text-xs text-muted-foreground mb-1 block">

View File

@@ -13,6 +13,7 @@ import { Button } from "@/components/ui/button";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { ExternalLink, Github, Plus, Trash2, X } from "lucide-react";
import { ChoosePathButton } from "./PathInstructionsModal";
interface ProjectPropertiesProps {
project: Project;
@@ -384,12 +385,15 @@ export function ProjectProperties({ project, onUpdate }: ProjectPropertiesProps)
</div>
{workspaceMode === "local" && (
<div className="space-y-1.5 rounded-md border border-border p-2">
<input
className="w-full rounded border border-border bg-transparent px-2 py-1 text-xs font-mono outline-none"
value={workspaceCwd}
onChange={(e) => setWorkspaceCwd(e.target.value)}
placeholder="/absolute/path/to/workspace"
/>
<div className="flex items-center gap-2">
<input
className="w-full rounded border border-border bg-transparent px-2 py-1 text-xs font-mono outline-none"
value={workspaceCwd}
onChange={(e) => setWorkspaceCwd(e.target.value)}
placeholder="/absolute/path/to/workspace"
/>
<ChoosePathButton />
</div>
<div className="flex items-center gap-2">
<Button
variant="outline"

View File

@@ -11,7 +11,7 @@ function ScrollArea({
return (
<ScrollAreaPrimitive.Root
data-slot="scroll-area"
className={cn("relative flex flex-col", className)}
className={cn("relative flex flex-col overflow-hidden", className)}
{...props}
>
<ScrollAreaPrimitive.Viewport