feat: Add date processed filter to Identify component and API
This commit introduces a new date processed filter in the Identify component, allowing users to filter faces based on the date they were processed. The API has been updated to support this new parameter, ensuring seamless integration with the frontend. Additionally, the date filters for date taken have been renamed for clarity. Documentation has been updated to reflect these changes.
This commit is contained in:
parent
17aeb5b823
commit
85dd6a68b3
@ -152,6 +152,7 @@ export const facesApi = {
|
||||
date_to?: string
|
||||
date_taken_from?: string
|
||||
date_taken_to?: string
|
||||
date_processed?: string
|
||||
date_processed_from?: string
|
||||
date_processed_to?: string
|
||||
sort_by?: 'quality' | 'date_taken' | 'date_added'
|
||||
|
||||
@ -18,6 +18,7 @@ export default function Identify() {
|
||||
const [sortDir, setSortDir] = useState<SortDir>('desc')
|
||||
const [dateFrom, setDateFrom] = useState<string>('')
|
||||
const [dateTo, setDateTo] = useState<string>('')
|
||||
const [dateProcessed, setDateProcessed] = useState<string>('')
|
||||
|
||||
const [currentIdx, setCurrentIdx] = useState(0)
|
||||
const currentFace = faces[currentIdx]
|
||||
@ -74,8 +75,9 @@ export default function Identify() {
|
||||
page: 1,
|
||||
page_size: pageSize,
|
||||
min_quality: minQuality,
|
||||
date_from: dateFrom || undefined,
|
||||
date_to: dateTo || undefined,
|
||||
date_taken_from: dateFrom || undefined,
|
||||
date_taken_to: dateTo || undefined,
|
||||
date_processed: dateProcessed || undefined,
|
||||
sort_by: sortBy,
|
||||
sort_dir: sortDir,
|
||||
tag_names: selectedTags.length > 0 ? selectedTags.join(', ') : undefined,
|
||||
@ -248,6 +250,7 @@ export default function Identify() {
|
||||
if (settings.sortDir !== undefined) setSortDir(settings.sortDir)
|
||||
if (settings.dateFrom !== undefined) setDateFrom(settings.dateFrom)
|
||||
if (settings.dateTo !== undefined) setDateTo(settings.dateTo)
|
||||
if (settings.dateProcessed !== undefined) setDateProcessed(settings.dateProcessed)
|
||||
if (settings.uniqueFacesOnly !== undefined) setUniqueFacesOnly(settings.uniqueFacesOnly)
|
||||
if (settings.compareEnabled !== undefined) setCompareEnabled(settings.compareEnabled)
|
||||
if (settings.selectedTags !== undefined) setSelectedTags(settings.selectedTags)
|
||||
@ -271,6 +274,7 @@ export default function Identify() {
|
||||
sortDir,
|
||||
dateFrom,
|
||||
dateTo,
|
||||
dateProcessed,
|
||||
uniqueFacesOnly,
|
||||
compareEnabled,
|
||||
selectedTags,
|
||||
@ -279,7 +283,7 @@ export default function Identify() {
|
||||
} catch (error) {
|
||||
console.error('Error saving settings to localStorage:', error)
|
||||
}
|
||||
}, [pageSize, minQuality, sortBy, sortDir, dateFrom, dateTo, uniqueFacesOnly, compareEnabled, selectedTags, settingsLoaded])
|
||||
}, [pageSize, minQuality, sortBy, sortDir, dateFrom, dateTo, dateProcessed, uniqueFacesOnly, compareEnabled, selectedTags, settingsLoaded])
|
||||
|
||||
// Initial load on mount (after settings are loaded)
|
||||
useEffect(() => {
|
||||
@ -521,18 +525,12 @@ export default function Identify() {
|
||||
<div className="p-4">
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700">Min Quality</label>
|
||||
<input type="range" min={0} max={1} step={0.05} value={minQuality}
|
||||
onChange={(e) => setMinQuality(parseFloat(e.target.value))} className="w-full" />
|
||||
<div className="text-xs text-gray-500">{(minQuality * 100).toFixed(0)}%</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700">Date From</label>
|
||||
<label className="block text-sm font-medium text-gray-700">Date Taken From</label>
|
||||
<input type="date" value={dateFrom} onChange={(e) => setDateFrom(e.target.value)}
|
||||
className="mt-1 block w-full border rounded px-2 py-1" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700">Date To</label>
|
||||
<label className="block text-sm font-medium text-gray-700">Date Taken To</label>
|
||||
<input type="date" value={dateTo} onChange={(e) => setDateTo(e.target.value)}
|
||||
className="mt-1 block w-full border rounded px-2 py-1" />
|
||||
</div>
|
||||
@ -553,6 +551,17 @@ export default function Identify() {
|
||||
<option value="asc">Asc</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700">Date Processed On</label>
|
||||
<input type="date" value={dateProcessed} onChange={(e) => setDateProcessed(e.target.value)}
|
||||
className="mt-1 block w-full border rounded px-2 py-1" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700">Min Quality</label>
|
||||
<input type="range" min={0} max={1} step={0.05} value={minQuality}
|
||||
onChange={(e) => setMinQuality(parseFloat(e.target.value))} className="w-full" />
|
||||
<div className="text-xs text-gray-500">{(minQuality * 100).toFixed(0)}%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
|
||||
@ -100,10 +100,11 @@ def process_faces(request: ProcessFacesRequest) -> ProcessFacesResponse:
|
||||
@router.get("/unidentified", response_model=UnidentifiedFacesResponse)
|
||||
def get_unidentified_faces(
|
||||
page: int = Query(1, ge=1),
|
||||
page_size: int = Query(50, ge=1, le=200),
|
||||
page_size: int = Query(50, ge=1, le=2000),
|
||||
min_quality: float = Query(0.0, ge=0.0, le=1.0),
|
||||
date_from: str | None = Query(None),
|
||||
date_to: str | None = Query(None),
|
||||
date_taken_from: str | None = Query(None, description="Filter by date taken (from)"),
|
||||
date_taken_to: str | None = Query(None, description="Filter by date taken (to)"),
|
||||
date_processed: str | None = Query(None, description="Filter by date processed (exact date)"),
|
||||
sort_by: str = Query("quality"),
|
||||
sort_dir: str = Query("desc"),
|
||||
tag_names: str | None = Query(None, description="Comma-separated tag names for filtering"),
|
||||
@ -113,8 +114,20 @@ def get_unidentified_faces(
|
||||
"""Get unidentified faces with filters and pagination."""
|
||||
from datetime import date as _date
|
||||
|
||||
df = _date.fromisoformat(date_from) if date_from else None
|
||||
dt = _date.fromisoformat(date_to) if date_to else None
|
||||
try:
|
||||
dtf = _date.fromisoformat(date_taken_from) if date_taken_from and date_taken_from.strip() else None
|
||||
except (ValueError, AttributeError, TypeError):
|
||||
dtf = None
|
||||
|
||||
try:
|
||||
dtt = _date.fromisoformat(date_taken_to) if date_taken_to and date_taken_to.strip() else None
|
||||
except (ValueError, AttributeError, TypeError):
|
||||
dtt = None
|
||||
|
||||
try:
|
||||
dp = _date.fromisoformat(date_processed) if date_processed and date_processed.strip() else None
|
||||
except (ValueError, AttributeError, TypeError):
|
||||
dp = None
|
||||
|
||||
# Parse tag names
|
||||
tag_names_list = None
|
||||
@ -126,8 +139,9 @@ def get_unidentified_faces(
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
min_quality=min_quality,
|
||||
date_from=df,
|
||||
date_to=dt,
|
||||
date_taken_from=dtf,
|
||||
date_taken_to=dtt,
|
||||
date_processed=dp,
|
||||
sort_by=sort_by,
|
||||
sort_dir=sort_dir,
|
||||
tag_names=tag_names_list,
|
||||
|
||||
@ -1200,6 +1200,7 @@ def list_unidentified_faces(
|
||||
date_to: Optional[date] = None,
|
||||
date_taken_from: Optional[date] = None,
|
||||
date_taken_to: Optional[date] = None,
|
||||
date_processed: Optional[date] = None,
|
||||
date_processed_from: Optional[date] = None,
|
||||
date_processed_to: Optional[date] = None,
|
||||
sort_by: str = "quality",
|
||||
@ -1263,6 +1264,9 @@ def list_unidentified_faces(
|
||||
query = query.filter(Photo.date_taken <= date_taken_to)
|
||||
|
||||
# Date processed filters (uses photo.date_added)
|
||||
if date_processed is not None:
|
||||
# Filter by exact date processed
|
||||
query = query.filter(func.date(Photo.date_added) == date_processed)
|
||||
if date_processed_from is not None:
|
||||
query = query.filter(func.date(Photo.date_added) >= date_processed_from)
|
||||
if date_processed_to is not None:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user