Convert the Admin UI sidebar to use the action framework.

Review Request #14721 — Created Dec. 2, 2025 and updated

Information

Review Board
release-7.1.x

Reviewers

The admin sidebar used to be composed based off of an HTML file
populated using state from a template tag, with template hooks to append
custom HTML to the sections. While there was some degree of
extensibility, it was a bit limited, requiring the consumer to generate
just the right HTML.

This change converts the sidebar to use actions instead. There's now an
action group per group in the sidebar, and an action per child.
Specialized sidebar action renderers take care of rendering with
existing support for the template hook points.

The Manage section has the most specializations. The group renderer
takes care of looking up the counts and Add Item URLs for each child
action, caching the results for quicker lookup. The item renderer then
provides this to a template, based on the cached state (falling back to
direct querying if not in the cache).

With this, extensions can now simply register actions in the Admin UI
sidebar, taking advantage of the built-in rendering and capabilities.

Tested all the links in the admin UI.

Tested fallback Manage item logic when the cache results come up empty.

Summary ID
Convert the Admin UI sidebar to use the action framework.
The admin sidebar used to be composed based off of an HTML file populated using state from a template tag, with template hooks to append custom HTML to the sections. While there was some degree of extensibility, it was a bit limited, requiring the consumer to generate just the right HTML. This change converts the sidebar to use actions instead. There's now an action group per group in the sidebar, and an action per child. Specialized sidebar action renderers take care of rendering with existing support for the template hook points. The Manage section has the most specializations. The group renderer takes care of looking up the counts and Add Item URLs for each child action, caching the results for quicker lookup. The item renderer then provides this to a template, based on the cached state (falling back to direct querying if not in the cache). With this, extensions can now simply register actions in the Admin UI sidebar, taking advantage of the built-in rendering and capabilities.
737a59ec0d0b9d1ba080d24d469a507099d90a91

Description From Last Updated

Can we add tests for some of the new behavior? get_default_admin_actions() get_default_admin_attachment_points() Item counts/urls.

daviddavid

Shouldn't this inherit from BaseAdminSidebarGroupAction

daviddavid

Shouldn't this inherit from BaseAdminSidebarGroupAction

daviddavid

This ends up creating the queryset object when the class is defined, which seems like it might create confusing bugs …

daviddavid

This should be typed to return Iterator[ActionAttachmentPoint]

daviddavid
david
  1. 
      
  2. Show all issues

    Can we add tests for some of the new behavior?

    • get_default_admin_actions()
    • get_default_admin_attachment_points()
    • Item counts/urls.
    1. Forgot to add the tests files. Adding and updating for some other changes I've made. But I don't know that there's really anything to gain from tests for get_default_admin_*, since these are just returning instances and don't contain any real logic. What were you wanting there?

  3. reviewboard/admin/actions.py (Diff revision 1)
     
     
    Show all issues

    Shouldn't this inherit from BaseAdminSidebarGroupAction

  4. reviewboard/admin/actions.py (Diff revision 1)
     
     
    Show all issues

    Shouldn't this inherit from BaseAdminSidebarGroupAction

  5. reviewboard/admin/actions.py (Diff revision 1)
     
     
    Show all issues

    This ends up creating the queryset object when the class is defined, which seems like it might create confusing bugs (especially in the case of running tests). I feel like this would be much better done as a property that can be reimplemented in subclasses and return a new QuerySet when needed.

    1. I had forgotten the second step in this pattern (which Django also uses), which is to turn the class-defined instance into a local one (adding a .all() at the end does this). I glossed over this part while working on another problem.

  6. reviewboard/admin/actions.py (Diff revision 1)
     
     
    Show all issues

    This should be typed to return Iterator[ActionAttachmentPoint]

  7. 
      
chipx86
Review request changed
Change Summary:
  • Manage action items can now define a model, with titles/URLs/querysets derived from that.
  • Caches are now longer and invalidated only when managed models are added/deleted.
  • Fixed the parent class for the sidebar group actions.
  • Renamed count_queryset to item_queryset.
  • Added get_item_queryset(), which returns a local instance instead of a shared copy.
  • Added exception handling around URL resolution, so a bad URL name doesn't break half the sidebar.
  • Added back an import to rbadmintags.
  • FixAddeded typing on get_default_admin_actions() and get_default_admin_attachment_points().
  • Added unit tests.
Commits:
Summary ID
Convert the Admin UI sidebar to use the action framework.
The admin sidebar used to be composed based off of an HTML file populated using state from a template tag, with template hooks to append custom HTML to the sections. While there was some degree of extensibility, it was a bit limited, requiring the consumer to generate just the right HTML. This change converts the sidebar to use actions instead. There's now an action group per group in the sidebar, and an action per child. Specialized sidebar action renderers take care of rendering with existing support for the template hook points. The Manage section has the most specializations. The group renderer takes care of looking up the counts and Add Item URLs for each child action, caching the results for quicker lookup. The item renderer then provides this to a template, based on the cached state (falling back to direct querying if not in the cache). With this, extensions can now simply register actions in the Admin UI sidebar, taking advantage of the built-in rendering and capabilities.
61244c3196e612e5e86f2e9ea69d602810c30082
Convert the Admin UI sidebar to use the action framework.
The admin sidebar used to be composed based off of an HTML file populated using state from a template tag, with template hooks to append custom HTML to the sections. While there was some degree of extensibility, it was a bit limited, requiring the consumer to generate just the right HTML. This change converts the sidebar to use actions instead. There's now an action group per group in the sidebar, and an action per child. Specialized sidebar action renderers take care of rendering with existing support for the template hook points. The Manage section has the most specializations. The group renderer takes care of looking up the counts and Add Item URLs for each child action, caching the results for quicker lookup. The item renderer then provides this to a template, based on the cached state (falling back to direct querying if not in the cache). With this, extensions can now simply register actions in the Admin UI sidebar, taking advantage of the built-in rendering and capabilities.
737a59ec0d0b9d1ba080d24d469a507099d90a91

Checks run (2 succeeded)

flake8 passed.
JSHint passed.