History

Show worktree name in thread delete confirmation

- Format orphaned worktree paths to display only the final segment - Apply formatting in Sidebar delete prompt for cleaner UX - Add tests for Unix, Windows, trailing slash, and fallback cases

Julius Marminge committed 9 months ago

Commit 4f5eb3b1 parent b6523a13 files · +44 −3Browse files

Unified · Split

3 files
  1. apps/web/src/components/Sidebar.tsx +5 −2
  2. apps/web/src/worktreeCleanup.test.ts +27 −1
  3. apps/web/src/worktreeCleanup.ts +12 −0
apps/web/src/components/Sidebar.tsx+5−2
@@ -12,7 +12,7 @@ import { · 11 unmodified lines
1212 type Thread,
1313 } from "../types";
1414 import { useNativeApi } from "../hooks/useNativeApi";
15−import { getOrphanedWorktreePathForThread } from "../worktreeCleanup";
15+import { formatWorktreePathForDisplay, getOrphanedWorktreePathForThread } from "../worktreeCleanup";
1616
1717 const THEME_CYCLE = { system: "light", light: "dark", dark: "system" } as const;
1818 function formatRelativeTime(iso: string): string {
@@ -265,12 +265,15 @@ export default function Sidebar() { · 246 unmodified lines
265265 if (!thread) return;
266266 const threadProject = state.projects.find((project) => project.id === thread.projectId);
267267 const orphanedWorktreePath = getOrphanedWorktreePathForThread(state.threads, threadId);
268+ const displayWorktreePath = orphanedWorktreePath
269+ ? formatWorktreePathForDisplay(orphanedWorktreePath)
270+ : null;
268271 const shouldDeleteWorktree =
269272 orphanedWorktreePath !== null &&
270273 (await api.dialogs.confirm(
271274 [
272275 "This thread is the only one linked to this worktree:",
273− orphanedWorktreePath,
276+ displayWorktreePath ?? orphanedWorktreePath,
274277 "",
275278 "Delete the worktree too?",
276279 ].join("\n"),
apps/web/src/worktreeCleanup.test.ts+27−1
@@ -1,7 +1,7 @@
11 import { describe, expect, it } from "vitest";
22
33 import { DEFAULT_THREAD_TERMINAL_HEIGHT, DEFAULT_THREAD_TERMINAL_ID, type Thread } from "./types";
4−import { getOrphanedWorktreePathForThread } from "./worktreeCleanup";
4+import { formatWorktreePathForDisplay, getOrphanedWorktreePathForThread } from "./worktreeCleanup";
55
66 function makeThread(overrides: Partial<Thread> = {}): Thread {
77 return {
@@ -69,3 +69,29 @@ describe("getOrphanedWorktreePathForThread", () => { · 61 unmodified lines
6969 expect(result).toBe("/tmp/repo/worktrees/feature-a");
7070 });
7171 });
72+
73+describe("formatWorktreePathForDisplay", () => {
74+ it("shows only the last path segment for unix-like paths", () => {
75+ const result = formatWorktreePathForDisplay(
76+ "/Users/julius/.t3/worktrees/codething-mvp/codething-4e609bb8",
77+ );
78+ expect(result).toBe("codething-4e609bb8");
79+ });
80+
81+ it("normalizes windows separators before selecting the final segment", () => {
82+ const result = formatWorktreePathForDisplay(
83+ "C:\\Users\\julius\\.t3\\worktrees\\codething-mvp\\codething-4e609bb8",
84+ );
85+ expect(result).toBe("codething-4e609bb8");
86+ });
87+
88+ it("uses the final segment even when outside ~/.t3/worktrees", () => {
89+ const result = formatWorktreePathForDisplay("/tmp/custom-worktrees/my-worktree");
90+ expect(result).toBe("my-worktree");
91+ });
92+
93+ it("ignores trailing slashes", () => {
94+ const result = formatWorktreePathForDisplay("/tmp/custom-worktrees/my-worktree/");
95+ expect(result).toBe("my-worktree");
96+ });
97+});
apps/web/src/worktreeCleanup.ts+12−0
@@ -31,3 +31,15 @@ export function getOrphanedWorktreePathForThread( · 30 unmodified lines
3131
3232 return isShared ? null : targetWorktreePath;
3333 }
34+
35+export function formatWorktreePathForDisplay(worktreePath: string): string {
36+ const trimmed = worktreePath.trim();
37+ if (!trimmed) {
38+ return worktreePath;
39+ }
40+
41+ const normalized = trimmed.replace(/\\/g, "/").replace(/\/+$/, "");
42+ const parts = normalized.split("/");
43+ const lastPart = parts[parts.length - 1]?.trim() ?? "";
44+ return lastPart.length > 0 ? lastPart : trimmed;
45+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t