feat(sidebar): grouped category render + UI (LC-79 phase 1b) #130
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/lc-79-sidebar-categories-phase1b"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
LC-79 phase 1b: surfaces the categories persisted by phase 1a PR #129 in the sidebar render. Together they cover LC-79's phase 1 scope (schema + CRUD + grouped render). Phases 2 (drag-and-drop) and 3 (collapsed-aggregate unread, mobile polish) are separate follow-ups.
Closes LC-79 phase 1b.
Data flow
load_sidebarreturns a third value alongside rooms and peers: aVec<SidebarCategoryGroup>. Each group bundles its rooms in user-controlled position order. Rooms with no assignment stay in the existingsidebar_roomsvec, rendered under "All rooms" when at least one category exists, or under the original "Rooms" header when none do. The bucketing is two small queries againstauth.db(categories + assignments), no chat.db work added.The new field threads through every view struct that today carries
sidebar_rooms: &[SidebarRoom](~25 sites acrossviews/{enclave,home,bookmarks,admin,pinned,settings,voice,dm,room,not_found,ws_fragments}.rs) and every handler that constructs them (~30 sites inroutes/). Mechanical pass: a regex-driven batch update covered the call sites uniformly.Sidebar UI
partials/sidebar.htmlrenders, in order:PATCH /sidebar/categories/{id}form that toggles collapsed (sendscollapsed=1when currently expanded so submit collapses; omits the field when collapsed so submit uncollapses). When expanded, the room list appears below.…menu on each category surfacing rename (PATCH /sidebar/categories/{id}withname=…) and delete (DELETE /sidebar/categories/{id}with a confirm prompt that mentions room fallback).+ Addform (POST /sidebar/categories) at the bottom of the nav scroll area.partials/sidebar_room_row.html(new) renders one room row. Whensidebar_categoriesis non-empty, a hover-revealed≡menu lists every category as aPATCH /sidebar/categories/{id}/rooms/{room_id}action plus a "Remove from category" entry (DELETE /sidebar/categories/rooms/{room_id}). The menu hides itself entirely when no categories exist so a user who has never used the feature sees the same sidebar as before.Compat
+ Addform at the bottom of the sidebar.load_chrome/load_sidebarnow also passsidebar_categoriesthrough; no functional drift expected since the new field defaults to an empty slice for those users.Test plan
just check(fmt + clippy across standalone + saas).just test(full standalone integration suite, all green)../dev/cargo test -p lets-chat-server --test routes_sidebar_categories(6 tests from phase 1a still pass).Follow-ups
PATCH /sidebar/categories/{id}/positions).Surfaces the categories persisted by phase 1a in the sidebar. `load_sidebar` now buckets categorized rooms into `SidebarCategoryGroup`s alongside the uncategorized fallback; the new field threads through every view struct that renders the sidebar (~25 sites). `partials/sidebar.html` iterates categories first (in user-controlled position order, collapsed-aware) then the "All rooms" fallback then DMs. A small "+ Add" form at the bottom of the nav lets the user create a category; each category gets a `…` menu with rename + delete; each room gets a hover-revealed `≡` menu listing all categories plus "Remove from category". Collapsed-state toggle: the category header is a `PATCH /sidebar/categories/{id}` form that includes `collapsed=1` when currently expanded (so submit collapses) and omits it when collapsed (so submit uncollapses), matching the existing checkbox semantics in `PatchCategoryForm`. Per-room move dropdown only renders when `sidebar_categories` is non-empty; users with no categories see the same sidebar shape as before phase 1a, just with the "+ Add" affordance below the list. Phase 2 (separate PR): drag-and-drop reorder. Phase 3: unread aggregation on collapsed categories + mobile layout polish.