You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tags are currently only visible on individual memory entries. Add a tag cloud to the workspace, nested-workspace, and project detail pages so users can see the tag landscape at each organizational level and drill into tag-filtered memory lists.
Scope
Per the tag-cloud scope decision, a workspace tag cloud aggregates tags from the entire workspace subtree: direct workspace memories + all projects + all nested workspaces (recursive).
Changes
Backend
New ITagCloudService / TagCloudService (auto-registered via [AutoRegisterInterfaces]), depending on NpgsqlDataSource — does not extend IStorage, so no test-fake churn.
GetProjectTagCountsAsync(ProjectId) — direct project memories.
New model TagCount { string Tag; int Count }.
New endpoint GET /api/memory/tags/cloud?workspaceId=&projectId= (mutually exclusive → 400) returning [{tag, count}], sorted by count desc then tag.
Frontend
Tag-cloud card on WorkspaceDetail.cshtml and ProjectDetail.cshtml.
Tags rendered as clickable badges with font-size scaled by count (min ~0.8rem → max ~1.5rem); click navigates to /memories?workspaceId=X&tag=Y (or projectId).
Summary
Tags are currently only visible on individual memory entries. Add a tag cloud to the workspace, nested-workspace, and project detail pages so users can see the tag landscape at each organizational level and drill into tag-filtered memory lists.
Scope
Per the tag-cloud scope decision, a workspace tag cloud aggregates tags from the entire workspace subtree: direct workspace memories + all projects + all nested workspaces (recursive).
Changes
Backend
ITagCloudService/TagCloudService(auto-registered via[AutoRegisterInterfaces]), depending onNpgsqlDataSource— does not extendIStorage, so no test-fake churn.GetWorkspaceSubtreeTagCountsAsync(WorkspaceId)— recursive CTE overworkspaces.parent_id,unnest(tags),owner_type = 0(workspace) /owner_type = 1(project).GetProjectTagCountsAsync(ProjectId)— direct project memories.TagCount { string Tag; int Count }.GET /api/memory/tags/cloud?workspaceId=&projectId=(mutually exclusive → 400) returning[{tag, count}], sorted by count desc then tag.Frontend
WorkspaceDetail.cshtmlandProjectDetail.cshtml./memories?workspaceId=X&tag=Y(orprojectId).loadTagCloud()+ its own section div) so the diff stays separable from Add tag clouds to workspace / nested workspace / project detail pages #2.site.css(per project convention,[data-theme="dark"]).Files
src/Memorizer/Services/ITagCloudService.cs,Services/TagCloudService.cs,Models/TagCount.cssrc/Memorizer/Controllers/MemoryController.cs,Views/Home/WorkspaceDetail.cshtml,Views/Home/ProjectDetail.cshtml,wwwroot/css/site.cssNotes