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:
+16
-3
@@ -1,6 +1,6 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { auth, type Tokens, type User } from './stores/auth.svelte';
|
||||
import type { Photo, Preferences } from './types';
|
||||
import type { Photo, Preferences, Tag } from './types';
|
||||
|
||||
export class ApiError extends Error {
|
||||
status: number;
|
||||
@@ -120,6 +120,19 @@ export const photosApi = {
|
||||
body: { ids, album_id: albumId }
|
||||
}),
|
||||
trash: () => api<{ photos: Photo[] }>('/trash'),
|
||||
restore: (id: string) => api<{ photo: Photo }>(`/photos/${id}/restore`, { method: 'POST' }),
|
||||
permanentDelete: (id: string) => api(`/photos/${id}/permanent`, { method: 'DELETE' })
|
||||
trashCount: () => api<{ count: number }>('/trash/count'),
|
||||
restore: (id: string, albumId?: string) =>
|
||||
api<{ photo: Photo }>(`/photos/${id}/restore`, {
|
||||
method: 'POST',
|
||||
body: albumId ? { album_id: albumId } : {}
|
||||
}),
|
||||
permanentDelete: (id: string) => api(`/photos/${id}/permanent`, { method: 'DELETE' }),
|
||||
addTag: (id: string, name: string) =>
|
||||
api<{ photo: Photo }>(`/photos/${id}/tags`, { method: 'POST', body: { name } }),
|
||||
removeTag: (id: string, tagId: string) =>
|
||||
api<{ photo: Photo }>(`/photos/${id}/tags/${tagId}`, { method: 'DELETE' })
|
||||
};
|
||||
|
||||
export const tagsApi = {
|
||||
list: (q = '') => api<{ tags: Tag[] }>(`/tags${q ? `?q=${encodeURIComponent(q)}` : ''}`)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user