feat: colored count badge on Colors sidebar entry
Adds a `colored` field to /library/stats counting non-discarded photos with a color_label set, mirroring how `rated` is exposed. The Colors sidebar entry now shows the live count and refreshes through the existing LIBRARY_STATS_QUERY_KEY invalidations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,8 @@ async def get_library_stats(db: AsyncSession = Depends(get_db)):
|
|||||||
- all_photos: non-discarded photos + videos (matches the All
|
- all_photos: non-discarded photos + videos (matches the All
|
||||||
Photos section's default filter)
|
Photos section's default filter)
|
||||||
- rated: non-discarded with rating >= 1
|
- rated: non-discarded with rating >= 1
|
||||||
|
- colored: non-discarded with a color_label set (matches the
|
||||||
|
Colors grouped view's labeled buckets)
|
||||||
- duplicates: non-discarded with is_duplicate = true
|
- duplicates: non-discarded with is_duplicate = true
|
||||||
- discarded: is_discarded = true
|
- discarded: is_discarded = true
|
||||||
- total_size: raw bytes across every row, including discarded
|
- total_size: raw bytes across every row, including discarded
|
||||||
@@ -52,6 +54,14 @@ async def get_library_stats(db: AsyncSession = Depends(get_db)):
|
|||||||
)
|
)
|
||||||
).scalar() or 0
|
).scalar() or 0
|
||||||
|
|
||||||
|
colored_count = (
|
||||||
|
await db.execute(
|
||||||
|
select(func.count(Photo.id)).where(
|
||||||
|
not_discarded, Photo.color_label.is_not(None)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).scalar() or 0
|
||||||
|
|
||||||
duplicates_count = (
|
duplicates_count = (
|
||||||
await db.execute(
|
await db.execute(
|
||||||
select(func.count(Photo.id)).where(
|
select(func.count(Photo.id)).where(
|
||||||
@@ -85,6 +95,7 @@ async def get_library_stats(db: AsyncSession = Depends(get_db)):
|
|||||||
return {
|
return {
|
||||||
"all_photos": all_photos_count,
|
"all_photos": all_photos_count,
|
||||||
"rated": rated_count,
|
"rated": rated_count,
|
||||||
|
"colored": colored_count,
|
||||||
"duplicates": duplicates_count,
|
"duplicates": duplicates_count,
|
||||||
"discarded": discarded_count,
|
"discarded": discarded_count,
|
||||||
"total_photos": photo_count,
|
"total_photos": photo_count,
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ export function LeftSidebar({ onCollapse, onOpenSettings }: LeftSidebarProps) {
|
|||||||
{ id: 'all-photos', label: 'All Photos', icon: <Image className="h-4 w-4" />, count: stats?.all_photos ?? 0 },
|
{ id: 'all-photos', label: 'All Photos', icon: <Image className="h-4 w-4" />, count: stats?.all_photos ?? 0 },
|
||||||
{ id: 'rated', label: 'Rated', icon: <Star className="h-4 w-4" />, count: stats?.rated ?? 0 },
|
{ id: 'rated', label: 'Rated', icon: <Star className="h-4 w-4" />, count: stats?.rated ?? 0 },
|
||||||
{ id: 'tags', label: 'Tags', icon: <TagIcon className="h-4 w-4" />, count: tagsTotalCount },
|
{ id: 'tags', label: 'Tags', icon: <TagIcon className="h-4 w-4" />, count: tagsTotalCount },
|
||||||
{ id: 'colors', label: 'Colors', icon: <Palette className="h-4 w-4" /> },
|
{ id: 'colors', label: 'Colors', icon: <Palette className="h-4 w-4" />, count: stats?.colored ?? 0 },
|
||||||
{ id: 'duplicates', label: 'Duplicates', icon: <Copy className="h-4 w-4" />, count: stats?.duplicates ?? 0 },
|
{ id: 'duplicates', label: 'Duplicates', icon: <Copy className="h-4 w-4" />, count: stats?.duplicates ?? 0 },
|
||||||
{ id: 'discarded', label: 'Discarded', icon: <Trash2 className="h-4 w-4" />, count: stats?.discarded ?? 0 },
|
{ id: 'discarded', label: 'Discarded', icon: <Trash2 className="h-4 w-4" />, count: stats?.discarded ?? 0 },
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -409,6 +409,7 @@ export interface DuplicateGroupsResponse {
|
|||||||
export interface LibraryStats {
|
export interface LibraryStats {
|
||||||
all_photos: number
|
all_photos: number
|
||||||
rated: number
|
rated: number
|
||||||
|
colored: number
|
||||||
duplicates: number
|
duplicates: number
|
||||||
discarded: number
|
discarded: number
|
||||||
total_photos: number
|
total_photos: number
|
||||||
|
|||||||
Reference in New Issue
Block a user