Skip to content

Detach attached folders from the Overview card - #108

Open
vivi7 wants to merge 1 commit into
doctly:mainfrom
vivi7:feat/overview-detach-folder
Open

vivi7 wants to merge 1 commit into
doctly:mainfrom
vivi7:feat/overview-detach-folder

Conversation

@vivi7

@vivi7 vivi7 commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Each row of the Attached Folders card on a project's Overview now ends with an X that detaches the folder, after a confirmation dialog.

Why

The Overview card has an Attach button but no way to take a folder away again. Detaching lives only in the Settings tab, behind an X that appears on hover, so from the Overview it looks as if a folder, once attached, can never be removed.

The Settings X also asked through native confirm() boxes. For a worktree the only question was "Also remove the checkout?", where Cancel meant "detach, but keep the checkout": there was no way to back out and keep the folder attached.

What it does

  • Overview: an X at the right end of every folder row, always visible, in a muted color that turns red on hover. The mode text (in place, worktree · branch) stays between the name and the X.
  • One dialog for both the Overview X and the Settings X, in the same style as Delete track:
    • title Detach <folder> from <project>?, the folder's full path (wrapped, not cut, since the name is at the end), Cancel and Detach;
    • for a plain folder: "Nothing on disk changes.";
    • for a worktree: an Also delete this checkout checkbox, unchecked by default, with "The branch <branch> and its commits stay." Checking it turns the button into Detach and delete;
    • Cancel or Escape changes nothing; focus starts on Cancel.
  • The existing follow-up for a checkout with uncommitted changes ("Remove it anyway and lose those changes?") is unchanged.

Implementation notes

  • public/projects-view.js:
    • the Overview row gets a .ws-frow-x button, wired in renderSideCards to the existing detachFolderFlow;
    • new confirmDetachFolder(project, folder), which resolves { removeWorktree } or null;
    • detachFolderFlow asks it instead of calling confirm(). The calls to detachProjectFolder are the same as before: {} for a plain folder, { removeWorktree } for a worktree, and the forced retry for a dirty checkout.
  • public/style.css: the Overview X stays visible (the other .ws-frow ghost buttons stay hover-only), keeps the row height, and the dialog path wraps.
  • No changes to the main process, the preload or the IPC.

Testing

  • New test/project-detach-folder.test.js. It loads the real detachFolderFlow from projects-view.js in a vm context, with the dialog stubbed, and checks that:
    • Cancel detaches nothing, for a plain folder and a worktree;
    • a plain folder is detached with nothing removed from disk;
    • a worktree keeps its checkout unless the dialog says to delete it;
    • a dirty checkout is forced only after the user agrees.
  • Against main's projects-view.js, all 5 tests fail.
  • npm test: the only failures are the two incremental columns upgrade a version-4/12 database… tests, which fail the same way on current main on my machine. (Two Git tests also fail with a global color.ui = always, as on main; they pass with color.ui=never.)
  • Manual check on macOS in the running app (electron . with an isolated SWITCHBOARD_DATA_DIR), in a project with a plain folder and a worktree, from the Overview:
    • both rows showed the X at the right end;
    • the X on the plain folder opened the dialog; Cancel kept the folder, Detach removed it from the card and left it on disk;
    • the X on the worktree showed the checkbox; checked, the button read Detach and delete, and confirming removed the checkout while the branch stayed in the source repository;
    • with no folders left, the card showed its empty state.

The Overview's Attached Folders card could attach a folder but never take
one away: detaching lived only in the Settings tab, behind an X that shows
on hover. Each folder row on the Overview now ends with an X, always in
sight and quiet until pointed at.

Both Xs open the same in-app dialog, in the style of Delete track: the
folder's full path, Cancel and Detach. A worktree also offers "Also delete
this checkout", unchecked by default, and says its branch and commits stay.
This replaces the native confirm() boxes, where a worktree could not be
kept attached: Cancel there meant "detach but keep the checkout". The
existing follow-up for a checkout with uncommitted changes is unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant