feat: Add sorting and filtering capabilities to Tags component with people names integration
This commit enhances the Tags component by introducing sorting functionality for various columns, including ID, filename, media type, and more. A filter option is added to display only photos with unidentified faces. Additionally, the API and data models are updated to include a new field for people names, allowing users to see identified individuals in the photo. The UI is improved with dropdowns for sorting and checkboxes for filtering, enhancing user experience. Documentation has been updated to reflect these changes.
This commit is contained in:
@@ -182,6 +182,7 @@ def get_photos_with_tags_endpoint(db: Session = Depends(get_db)) -> PhotosWithTa
|
||||
face_count=p['face_count'],
|
||||
unidentified_face_count=p['unidentified_face_count'],
|
||||
tags=p['tags'],
|
||||
people_names=p.get('people_names', ''),
|
||||
)
|
||||
for p in photos_data
|
||||
]
|
||||
|
||||
@@ -87,6 +87,7 @@ class PhotoWithTagsItem(BaseModel):
|
||||
face_count: int
|
||||
unidentified_face_count: int # Count of faces with person_id IS NULL
|
||||
tags: str # Comma-separated tags string (matching desktop)
|
||||
people_names: str = "" # Comma-separated people names string
|
||||
|
||||
|
||||
class PhotosWithTagsResponse(BaseModel):
|
||||
|
||||
@@ -7,7 +7,7 @@ from datetime import datetime
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from src.web.db.models import Photo, PhotoTagLinkage, Tag, Face
|
||||
from src.web.db.models import Photo, PhotoTagLinkage, Tag, Face, Person
|
||||
|
||||
|
||||
def list_tags(db: Session) -> List[Tag]:
|
||||
@@ -268,6 +268,31 @@ def get_photos_with_tags(db: Session) -> List[dict]:
|
||||
)
|
||||
tags = ", ".join([t[0] for t in tags_query]) if tags_query else ""
|
||||
|
||||
# Get people names as comma-separated string (unique people identified in photo)
|
||||
people_query = (
|
||||
db.query(Person)
|
||||
.join(Face, Person.id == Face.person_id)
|
||||
.filter(Face.photo_id == photo.id)
|
||||
.filter(Face.person_id.isnot(None))
|
||||
.order_by(Person.last_name, Person.first_name)
|
||||
.distinct()
|
||||
.all()
|
||||
)
|
||||
people_names = []
|
||||
for person in people_query:
|
||||
name_parts = []
|
||||
if person.first_name:
|
||||
name_parts.append(person.first_name)
|
||||
if person.middle_name:
|
||||
name_parts.append(person.middle_name)
|
||||
if person.last_name:
|
||||
name_parts.append(person.last_name)
|
||||
if person.maiden_name:
|
||||
name_parts.append(f"({person.maiden_name})")
|
||||
full_name = " ".join(name_parts) if name_parts else "Unknown"
|
||||
people_names.append(full_name)
|
||||
people_names_str = ", ".join(people_names) if people_names else ""
|
||||
|
||||
result.append({
|
||||
'id': photo.id,
|
||||
'filename': photo.filename,
|
||||
@@ -278,6 +303,8 @@ def get_photos_with_tags(db: Session) -> List[dict]:
|
||||
'face_count': face_count,
|
||||
'unidentified_face_count': unidentified_face_count,
|
||||
'tags': tags,
|
||||
'people_names': people_names_str,
|
||||
'media_type': photo.media_type or 'image',
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user