feat: photo multiselect, move/copy, trash and compact chrome
- backend: soft delete + trash (photos.deleted_at, migration 000005), GET /trash, restore, permanent delete with storage-key refcount (S3 objects removed only when no other album references them); batch endpoints photo-batch/{delete,move,copy} - metadata only, copies clone rows sharing storage keys
- frontend: Ctrl/Shift multiselect; right-panel 'Действия' as icon text rows (Открыть (просмотр), Переместить, Копировать, Удалить); drag selected photos onto rail album -> TransferDialog; /trash route; trash entry as last item in the left rail; empty right panel hidden on overview
- frontend: compact top bars (app header and viewer), compact theme switcher
- openspec: sync lightroom-workspace-ui artifacts (photos/ui-workspace specs, design #20-24, tasks 9.11-9.17)
This commit is contained in:
@@ -53,3 +53,37 @@
|
||||
#### Scenario: Фото без метаданных
|
||||
- **WHEN** загружается фото без читаемых EXIF
|
||||
- **THEN** данные фото не содержат атрибутов, а загрузка выполняется успешно
|
||||
|
||||
### Requirement: Перенос и копирование фото между альбомами
|
||||
Пользователь с правом удаления в исходном альбоме и правом загрузки в целевом SHALL иметь
|
||||
возможность перенести или скопировать фото в другой альбом. Операции SHALL изменять только
|
||||
метаданные и SHALL не изменять объекты хранилища.
|
||||
|
||||
#### Scenario: Перенос
|
||||
- **WHEN** пользователь переносит фото в другой альбом
|
||||
- **THEN** фото исчезает из исходного альбома и появляется в целевом, объекты S3 не меняются
|
||||
|
||||
#### Scenario: Копирование
|
||||
- **WHEN** пользователь копирует фото в другой альбом
|
||||
- **THEN** в целевом альбоме появляется новая запись, ссылающаяся на те же объекты S3
|
||||
|
||||
### Requirement: Корзина фото
|
||||
Удаление фото SHALL помещать его в корзину (мягкое удаление). Восстановление SHALL возвращать
|
||||
фото в его альбом. Окончательное удаление SHALL удалять запись, а объекты хранилища SHALL
|
||||
удаляться только когда на них не остаётся ссылок ни в одном альбоме.
|
||||
|
||||
#### Scenario: Удаление в корзину
|
||||
- **WHEN** пользователь удаляет фото
|
||||
- **THEN** фото пропадает из альбома и появляется в корзине
|
||||
|
||||
#### Scenario: Восстановление
|
||||
- **WHEN** пользователь восстанавливает фото из корзины
|
||||
- **THEN** фото возвращается в свой альбом
|
||||
|
||||
#### Scenario: Окончательное удаление без ссылок
|
||||
- **WHEN** пользователь удаляет фото из корзины навсегда, и на те же объекты нет ссылок в других альбомах
|
||||
- **THEN** запись и объекты хранилища удаляются
|
||||
|
||||
#### Scenario: Окончательное удаление при наличии ссылок
|
||||
- **WHEN** на объект хранилища ссылается копия в другом альбоме
|
||||
- **THEN** запись удаляется, а объект хранилища сохраняется
|
||||
|
||||
@@ -277,3 +277,49 @@ SHALL отображаться вне каркаса, но в общей тем
|
||||
#### Scenario: Смена альбома
|
||||
- **WHEN** пользователь переходит в другой альбом
|
||||
- **THEN** отметка выбора сбрасывается
|
||||
|
||||
### Requirement: Мультивыбор фото в сетке
|
||||
В режиме альбома пользователь SHALL выбирать несколько фото: обычный клик — одно фото,
|
||||
Ctrl/Cmd-клик — добавить или убрать, Shift-клик — диапазон. Выбранные фото SHALL быть отмечены.
|
||||
|
||||
#### Scenario: Мультивыбор
|
||||
- **WHEN** пользователь кликает по фото с зажатым Ctrl/Cmd или Shift
|
||||
- **THEN** соответствующие фото отмечены, а панель показывает количество выбранных
|
||||
|
||||
### Requirement: Действия с выбранными фото
|
||||
Когда выбрано одно или несколько фото, правая панель SHALL показывать раздел «Действия» со
|
||||
строками-пунктами (иконка + подпись) «Открыть (просмотр)», «Переместить», «Копировать» и
|
||||
«Удалить»; удаление SHALL подтверждаться диалогом.
|
||||
|
||||
#### Scenario: Действия
|
||||
- **WHEN** выбрано одно или несколько фото
|
||||
- **THEN** панель показывает раздел «Действия» с пунктами «Открыть (просмотр)», «Переместить», «Копировать» и «Удалить»
|
||||
|
||||
### Requirement: Перетаскивание выбранных фото на альбом
|
||||
Выбранные фото SHALL перетаскиваться на альбом в рейле; при отпускании SHALL открываться
|
||||
диалог выбора переноса или копирования с указанием целевого альбома. Во время такого
|
||||
перетаскивания зона загрузки файлов SHALL не показываться.
|
||||
|
||||
#### Scenario: Перетаскивание на альбом
|
||||
- **WHEN** пользователь перетаскивает выделенные фото на альбом в рейле и отпускает
|
||||
- **THEN** открывается диалог с выбором переноса/копирования и целевым альбомом
|
||||
|
||||
### Requirement: Корзина в списке альбомов
|
||||
Рейл альбомов SHALL содержать вход в корзину последним элементом списка (с иконкой корзины).
|
||||
Экран обзора альбомов SHALL не показывать пустую правую панель.
|
||||
|
||||
#### Scenario: Вход в корзину
|
||||
- **WHEN** пользователь открывает приложение
|
||||
- **THEN** в левом рейле последним элементом списка показана «Корзина» с иконкой корзины
|
||||
|
||||
#### Scenario: Обзор без панели
|
||||
- **WHEN** пользователь открывает обзор альбомов
|
||||
- **THEN** правая панель не отображается
|
||||
|
||||
### Requirement: Компактный верхний хром
|
||||
Верхняя панель приложения и верхняя панель режима просмотра SHALL иметь минимальную высоту
|
||||
(узкие отступы, иконочные органы управления), сохраняя все действия доступными.
|
||||
|
||||
#### Scenario: Компактные верхние панели
|
||||
- **WHEN** открыт список альбомов или режим просмотра фото
|
||||
- **THEN** верхняя панель занимает минимум высоты, а её действия (навигация, полный экран, скачивание, удаление) доступны
|
||||
|
||||
Reference in New Issue
Block a user