Skip to content

Decompose render: left sidebar as View<SidebarPanel> with SidebarSnapshot #204

Description

@MasonRhodesDev

Context

While auditing the render architecture in #203, the left sidebar was identified as the highest-payoff decomposition target.

Currently left_sidebar.rs is a collection of &self render helpers called inline from AnotherOneApp::render. Any state change anywhere in the app triggers a full re-render of the sidebar even when its specific state (project list, task list, expand state, context menus) didn't change.

What to do

Mirror the existing RightSidebarPanel pattern exactly:

  1. Define a SidebarSnapshot struct capturing everything the sidebar needs: projects, tasks, expanded repo IDs, UI state (pinned tasks, last active section), and the per-task menu/rename/delete-confirm state that currently lives on AnotherOneApp.
  2. Create struct SidebarPanel implementing Render, storing the snapshot plus local interaction state (sidebar_task_menu, sidebar_task_rename, sidebar_task_delete_confirm, sidebar_task_last_click).
  3. Store sidebar_panel: Entity<SidebarPanel> on AnotherOneApp.
  4. In the drain tick, compute a fresh SidebarSnapshot only when project/task state actually changed (gate behind a dirty flag like sidebar_changed), push it to SidebarPanel and call cx.notify() on it. Terminal-output ticks must not notify the sidebar.
  5. Remove the sidebar-only fields from AnotherOneApp (5–6 fields).

Why this is the right next step

  • RightSidebarPanel already proves the pattern works in this codebase.
  • The sidebar's state drivers (project/task mutations, daemon ProjectList pushes) are low-frequency (<1/sec) and already separated from terminal-output ticks by the drain loop.
  • Sidebar context-menu state (sidebar_task_menu, etc.) has zero cross-cutting dependencies — it can move directly into the new view.
  • project_store is the only broad dependency; a SidebarSnapshot severs it cleanly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions