feat(workspace): deleted folders go to the trash as a whole, after a confirmation

A deleted personal folder is kept in trashed_folders with its subfolders;
its notes are trashed and tied to it. The trash lists the folder as one
entry with its note count; restoring brings back the folder tree (empty
subfolders too) and all notes, deleting for good, emptying the trash and
the notes trash delay remove it with its notes. Folders in shared folders
keep the old way.

Deleting a folder now asks first, in a small popover at the click
(ConfirmPopover, documented in ui-patterns).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-11-02 19:36:22 +01:00
1 parent 9dcfa6c27e
commit b26b07cfea
18 files changed
+564 -25

No files matched your search

+18
View File
@@ -133,11 +133,13 @@ func (s *Store) DeleteFolder(userID, folderPath string) ([]string, error) {
var deletedDocIDs []string
var writes []sqlStmt
seenDocID := make(map[string]bool)
inSharedFolder := false
mounts, _, err := s.getUserFolderMounts(userID)
if err == nil {
sfID, subPath, isMatch := matchMountPath(clean, mounts)
if isMatch && sfID != "" {
inSharedFolder = true
if subPath == "" {
// Root of a shared folder
shFolder, sfErr := s.GetSharedFolderByID(userID, sfID)
@@ -201,6 +203,22 @@ func (s *Store) DeleteFolder(userID, folderPath string) ([]string, error) {
for _, id := range deletedDocIDs {
writes = append(writes, trashStmts(userID, id)...)
}
// A personal folder goes to the trash as a whole (with its subfolders), so it can come back as it was
if !inSharedFolder {
subfolders := []string{}
if frows, err := s.db.Query(`SELECT path FROM workspace_folders WHERE user_id = ? AND (shared_folder_id = '' OR shared_folder_id IS NULL)
AND path LIKE ?`, userID, clean+"/%"); err == nil {
for frows.Next() {
var p string
if frows.Scan(&p) == nil {
subfolders = append(subfolders, p)
}
}
_ = frows.Close()
}
_, folderWrites := trashFolderStmts(userID, clean, subfolders, deletedDocIDs)
writes = append(writes, folderWrites...)
}
// Also clear any personal folder placements for shared notes in this folder
writes = append(writes,