)}
```
**Utils Fix** (`/opt/media-downloader/web/frontend/src/lib/utils.ts`):
**formatDate Null Safety** (Lines 20-36):
```typescript
export function formatDate(date: string | undefined | null) {
if (!date) return 'N/A'
const d = date.includes(' ')
? new Date(date.replace(' ', 'T') + 'Z')
: new Date(date)
return d.toLocaleString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: true
})
}
```
---
### Version Files Updated
- `VERSION`: 6.40.5
- `README.md`: Added new feature to key features list
- `web/frontend/package.json`: Updated version
- `data/changelog.json`: Added version 6.40.5 entry with all changes
---
## [6.38.7] - 2025-11-22
### 🚀 Review Page Bulk Actions & Performance Improvements
This minor release adds powerful bulk action buttons to the Review page and significantly improves performance for large batch operations by implementing server-side batch processing.
---
### Features
#### Bulk Action Buttons
- **Delete All Button**: Delete all items in review queue with a single click
- **Keep All Button**: Move all review items to final destination at once
- **Dynamic Count Display**: Buttons show total count (e.g., "Delete All (309)")
- **Confirmation Dialog**: Shows exact count before executing bulk operations
- **Smart Disabled State**: Buttons disable when queue is empty or operations are in progress
#### Performance Improvements
- **Server-Side Batch Delete**: All deletions processed in single API request
- **No Rate Limiting**: Avoids throttling issues that occurred with parallel requests
- **10-100x Faster**: Bulk operations complete in seconds instead of minutes
- **Database Transaction**: All operations execute in single atomic transaction
- **Automatic Cleanup**: Orphaned database records are cleaned up automatically
---
### Bug Fixes
- **Fixed**: Delete All/Keep All now operate on entire review queue, not just visible thumbnails
- **Fixed**: Rate limiting issues when deleting large batches of files (300+)
- **Fixed**: Orphaned database records for files missing from disk are now cleaned up automatically
- **Improved**: Batch delete returns detailed results showing succeeded/failed counts
---
### Technical Changes
**Review Page** (`/opt/media-downloader/web/frontend/src/pages/Review.tsx`):
**New Handler Functions** (Lines 505-534):
```typescript
const handleDeleteAll = async () => {
const total = reviewData?.total || 0
if (total === 0) return
if (confirm(`Delete ALL ${total} items in the review queue? This cannot be undone.`)) {
const response = await api.getAllReviewFilePaths()
batchDeleteMutation.mutate(response.file_paths)
}
}
const handleKeepAll = async () => {
const total = reviewData?.total || 0
if (total === 0) return
const response = await api.getAllReviewFilePaths()
setSelectedItems(new Set(response.file_paths))
setShowKeepModal(true)
}
```
**UI Buttons** (Lines 638-674):
```typescript