feat: context menus, unified photo panel, tags, album trash and counters

- backend: deleting an album moves its photos to the trash without losing files (photos.album_id nullable, FK ON DELETE SET NULL, migration 000006; dropped S3 prefix delete); restore accepts an album target (album_required when the album is gone); user-scoped tags (000007) with GET /tags, POST/DELETE /photos/:id/tags, tags included in photo responses; GET /trash/count
- frontend: right-click context menus for photos (grid + viewer) and albums (rail + overview); single shared PhotoPanel reused in viewer and gallery selection (not a copy); viewer download/delete moved to the panel 'Действия'; transparent compact viewer top bar; trash entry as last rail item with per-album photo counts and trash count; album rename/delete dialogs
- openspec: sync lightroom-workspace-ui artifacts (specs photos/ui-workspace, design #24-30, tasks 9.17-9.24)
This commit is contained in:
iu
2026-10-10 22:45:41 +03:00
parent 2d6a3fea1a
commit 61b45b2742
37 changed files with 1639 additions and 328 deletions
+4
View File
@@ -139,11 +139,15 @@ func (s *Server) Router() *gin.Engine {
authed.GET("/photos/:id/download", photosHandler.Download)
authed.POST("/photos/:id/restore", photosHandler.Restore)
authed.DELETE("/photos/:id/permanent", photosHandler.PermanentDelete)
authed.POST("/photos/:id/tags", photosHandler.AddTag)
authed.DELETE("/photos/:id/tags/:tag_id", photosHandler.RemoveTag)
authed.GET("/tags", photosHandler.Tags)
authed.POST("/photo-batch/delete", photosHandler.DeleteBatch)
authed.POST("/photo-batch/move", photosHandler.MoveBatch)
authed.POST("/photo-batch/copy", photosHandler.CopyBatch)
authed.GET("/trash", photosHandler.Trash)
authed.GET("/trash/count", photosHandler.TrashCount)
authed.POST("/photos/:id/likes", socialHandler.AddLike)
authed.DELETE("/photos/:id/likes", socialHandler.RemoveLike)