Remove the organizer's Preview and apply section

The preview/apply flow on the Organize tab did not work as expected, so
it is removed along with its backend: the stored per-pair preview, the
/organize/preview, /organize/plan and /organize/apply endpoints and
their UI and types.

The File naming card stays, and renaming now happens only through
"Organize automatically" during scans, which keeps the underlying
planning/moving code (now internal), undo, crash recovery and dry run.
The rename-folders warning is unchanged. Tests now drive the kept
planning and moving code directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cdnutterandClaude Opus 5.5 committed 2026-09-29 13:18:40 -07:00
1 parent dbcf562f7e
commit 96ea856dfd
8 files changed
+76 -462

No files matched your search

-54
View File
@@ -91,9 +91,6 @@ func (s *Server) Handler() http.Handler {
r.Get("/files", s.handleFiles)
r.Post("/tags/read", s.handleReadTags)
r.Post("/tags", s.handleEditTags)
r.Post("/organize/preview", s.handleOrganizePreview)
r.Get("/organize/plan", s.handleOrganizePlan)
r.Post("/organize/apply", s.handleOrganizeApply)
r.Get("/renames", s.handleRenamePreview)
r.Post("/renames", s.handleRenames)
r.Post("/link-identical", s.handleLinkIdentical)
@@ -746,54 +743,3 @@ func (s *Server) handleEditTags(w http.ResponseWriter, r *http.Request) {
s.log.Info("tag edit started", "pair", id, "side", body.Side, "files", len(body.Paths), "fields", len(body.Set), "separate", body.Separate)
writeJSON(w, 202, j)
}
// ---- organizer ----
func (s *Server) handleOrganizePreview(w http.ResponseWriter, r *http.Request) {
id, _ := idParam(r)
var body struct {
Side string `json:"side"` // slave, master or both
}
if !readJSON(w, r, &body) {
return
}
j, err := s.eng.StartOrganizePlan(id, body.Side)
if err != nil {
opErr(w, err)
return
}
writeJSON(w, 202, j)
}
func (s *Server) handleOrganizePlan(w http.ResponseWriter, r *http.Request) {
id, _ := idParam(r)
q := r.URL.Query()
offset, _ := strconv.Atoi(q.Get("offset"))
limit, _ := strconv.Atoi(q.Get("limit"))
plan, items, total := s.eng.OrganizePlanFor(id, q.Get("filter"), offset, limit)
if plan == nil {
writeJSON(w, 200, map[string]any{"plan": nil})
return
}
if items == nil {
items = []engine.OrganizeItem{}
}
writeJSON(w, 200, map[string]any{"plan": plan, "items": items, "total": total})
}
func (s *Server) handleOrganizeApply(w http.ResponseWriter, r *http.Request) {
id, _ := idParam(r)
var body struct {
IDs []int `json:"ids"` // empty: every rename in the preview
}
if !readJSON(w, r, &body) {
return
}
j, err := s.eng.StartOrganizeApply(id, body.IDs)
if err != nil {
opErr(w, err)
return
}
s.log.Info("organize started", "pair", id, "selected", len(body.IDs))
writeJSON(w, 202, j)
}