feat(web): /tags tabs + keyword surfacing + dup tab restyle
- /tags hosts four tabs (Labels (auto) / Keywords / Ratings / Colors), URL-driven with pagination on the label + keyword grids; ratings and colors stay as fixed buckets. - /duplicates tabs (Stacks / Cross-folder) restyled to pill row in the Toolbar to match /tags; tab state moved into the route and bound to ?tab=... - New aggregateKeywords() service fans out per-photo getPhoto calls so user-typed Details.Keywords surface on /tags (PhotoPrism's /labels only returns classifier output). - RightSidebar renders photo.Labels[] as dashed-border chips after the Keywords section, each linking to /?q=label:slug. - /colors and /ratings routes redirect to /tags?tab=colors|ratings so old bookmarks still land somewhere useful; LeftSidebar drops their entries and the Tags badge now sums labels + ratings + colors. - listFolderCounts dedupes by UID (merged=false returns one row per FILE, so HEIC+JPG / Live Photo / RAW+JPG pairs were inflating folder counts ~2x). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -352,9 +352,19 @@
|
||||
{ kind: 'route', href: '/inbox', label: 'Inbox', getCount: () => importQuery.data?.files },
|
||||
{ kind: 'section', id: 'favorites', label: 'Favorites', getCount: () => configQuery.data?.count?.favorites },
|
||||
{ kind: 'route', href: '/map', label: 'Map', getCount: () => configQuery.data?.count?.places },
|
||||
{ kind: 'route', href: '/ratings', label: 'Ratings', getCount: () => ratingsCount },
|
||||
{ kind: 'route', href: '/colors', label: 'Colors', getCount: () => colorsCount },
|
||||
{ kind: 'route', href: '/tags', label: 'Tags', getCount: () => configQuery.data?.count?.labels }
|
||||
// Tags hosts four tabs (Labels (auto) / Keywords / Ratings / Colors);
|
||||
// the badge shows total labels + keywords + ratings + colors so the
|
||||
// number reflects the combined "things you can filter by" surface.
|
||||
{
|
||||
kind: 'route',
|
||||
href: '/tags',
|
||||
label: 'Tags',
|
||||
getCount: () => {
|
||||
const labels = configQuery.data?.count?.labels;
|
||||
if (labels === undefined) return undefined;
|
||||
return labels + ratingsCount + colorsCount;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const manageViews: ViewItem[] = [
|
||||
|
||||
Reference in New Issue
Block a user