Implement Ctrl+A Select All and Batch Reset functionality

This commit is contained in:
Tiberiu Ichim 2026-02-15 16:33:16 +02:00
parent 23034e6672
commit f7506e84d3
9 changed files with 266 additions and 3 deletions

View file

@ -0,0 +1,46 @@
# Batch Reset Metadata Specification
## Overview
The "Batch Reset Metadata" feature allows users to reset the metadata for multiple selected library items (books, podcasts, etc.) at once. This action reverts the items' metadata to what is found in the file system (tags, folder structure, OPF files), removing any manual edits stored in the database or `metadata.json` files.
## Date
2026-02-15
## User Interface
### Frontend
- **Component**: `client/components/app/Appbar.vue`
- **Trigger**: Context menu in the selection mode app bar (when multiple items are selected).
- **Visibility**:
- Available when multiple items are selected.
- Only available if the user has "Update" permissions.
- **Interaction**:
- Clicking "Reset Metadata" triggers a confirmation dialog.
- **Confirmation Message**: "Are you sure you want to reset metadata for ${n} items? This will remove metadata files and re-scan the items from files."
- **Action**: detailed in Backend Logic.
- **Feedback**:
- Success: Toast notification "Batch reset metadata successful".
- Failure: Error toast notification.
## Backend Logic
### Controller
- **Controller**: `LibraryItemController`
- **Method**: `batchResetMetadata(req, res)`
- **Logic**:
1. **Permission Check**: Verify `req.user.canUpdate`. Return 403 if not.
2. **Input Validation**: Check `libraryItemIds` array in body.
3. **Retrieve Items**: Fetch items by IDs.
4. **Process Loop**: Iterate through each item:
- **Remove Server Metadata**: Delete `/metadata/items/<id>/metadata.json` if exists.
- **Remove Local Metadata**: Delete `<item_path>/metadata.json` if exists (and not a single file item).
- **Reset Cover**: Set `media.coverPath` to `null`.
- **Re-Scan**: Trigger `LibraryItemScanner.scanLibraryItem(id)`.
5. **Response**: JSON object `{ success: true, results: [...] }`.
### API Router
- **Route**: `POST /api/items/batch/reset-metadata`
- **Handler**: `LibraryItemController.batchResetMetadata`
## Artifacts
- This specification is saved as `artifacts/2026-02-15/batch_reset.md`.

View file

@ -0,0 +1,19 @@
# Batch Reset Metadata Implementation Status
## Completed
- [x] Specification created (`artifacts/2026-02-15/batch_reset.md`)
- [x] Backend logic implemented in `server/controllers/LibraryItemController.js` (`batchResetMetadata`)
- [x] API route registered in `server/routers/ApiRouter.js` (`POST /api/items/batch/reset-metadata`)
- [x] Frontend UI updated in `client/components/app/Appbar.vue` (Menu item + Handler)
## Verification
- Syntax checked for backend files.
- Manual verification required by user:
1. Select multiple books/library items.
2. Click the context menu (three dots) in the selection bar.
3. Click "Reset Metadata".
4. Confirm the dialog.
5. Verify items are re-scanned and metadata reset.
## Note
- Localization string for confirmation message is currently hardcoded in English.

View file

@ -0,0 +1,36 @@
# Select All Keyboard Shortcut Specification
## Overview
Enable `Ctrl+A` (or `Cmd+A` on macOS) to select all items in the library listing screen.
## Date
2026-02-15
## User Interface
- **Component**: `client/components/app/LazyBookshelf.vue`
- **Trigger**: Global `keydown` event listener active when the bookshelf is mounted.
- **Shortcut**: `Ctrl+A` / `Cmd+A`.
- **Behavior**:
- Selects all currently loaded items in the bookshelf.
- Sets a `isSelectAll` flag that automatically selects newly loaded items as the user scrolls.
- Updates the "Selection Mode" UI with the total count of selected items.
- Clicking/Deselecting an individual item while `isSelectAll` is active will toggle off the `isSelectAll` persistent state (but keep existing selections).
## Implementation Details
### Vuex Store
- **File**: `client/store/globals.js`
- **Mutation**: `addBatchMediaItemsSelected`
- **Purpose**: Efficiently add a large number of items to the `selectedMediaItems` array without duplicates.
### LazyBookshelf Component
- **Methods**:
- `handleKeyDown(e)`: Detects the shortcut and calls `selectAll()`.
- `selectAll()`: Iterates through loaded `entities`, builds media item objects, and commits them to the store.
- `mountEntities()` Extension: Check `isSelectAll` flag and auto-select items as they are rendered.
- **Events**:
- Listen for `keydown` on `window`.
- Handle `bookshelf_clear_selection` event to reset `isSelectAll` flag.
## Artifacts
- This specification is saved as `artifacts/2026-02-15/select_all.md`.