Skip to content

OPS-1160: OPS-1181: New templates page#1784

Merged
Alek99 merged 18 commits intomainfrom
carlos/templates-ui
Mar 24, 2026
Merged

OPS-1160: OPS-1181: New templates page#1784
Alek99 merged 18 commits intomainfrom
carlos/templates-ui

Conversation

@carlosabadia
Copy link
Collaborator

No description provided.

@linear
Copy link

linear bot commented Mar 18, 2026

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 18, 2026

Greptile Summary

This PR introduces a full Templates section to the reflex.dev website, including a templates listing page (/templates) with search/filter sidebar, individual template detail pages (/templates/[id]), a new secondary_page decorator/layout, a secondary navbar, and a reusable async HTTP client backed by a singleton aiohttp.ClientSession. Backend data is fetched from the Reflex Build API using Reflex background events (correctly following the project's async pattern). The Route model is also migrated from reflex.base.Base to a standard @dataclass.

Key findings:

  • Critical — all three CTA buttons in the detail sidebar do the same thing: links_section() in sidebar.py wires "View Docs" and "Download Code" to redirect_to_template, making them behave identically to "Use This Template". These buttons need distinct handlers.
  • State bug — templates grid can appear empty after visiting a detail page: load_template_details populates self._all_templates but never sets self.tags. When the user then navigates to /templates, the early-return path in load_templates derives checked_tags from the still-empty self.tags, resulting in an empty checked_tags set that hides every template that has at least one tag.
  • Dead code — menu_item never invoked: A fully-implemented active-state nav helper is defined in secondary_navbar.py but no call site exists in navigation_menu().
  • rx.el.a with to= prop: Several new components pass to= to rx.el.a (a raw HTML anchor) rather than href=, which is likely to silently fail navigation.

Confidence Score: 2/5

  • Not safe to merge — two separate bugs will cause broken UX on both the templates listing and detail pages.
  • There is a critical UX bug where "View Docs" and "Download Code" misbehave, and a state management bug that causes the templates grid to render empty under a common navigation pattern. Both need to be fixed before this page ships.
  • pcweb/pages/templates/template_details/views/sidebar.py (wrong on_click handlers) and pcweb/pages/templates/templates_state.py (missing tag computation in load_template_details).

Important Files Changed

Filename Overview
pcweb/pages/templates/template_details/views/sidebar.py New sidebar for template detail page — critical bug: "View Docs" and "Download Code" both call redirect_to_template, identical to "Use This Template".
pcweb/pages/templates/templates_state.py Core state with background event handlers for loading/filtering templates — load_template_details populates _all_templates but omits tags, breaking the templates listing page when navigated to after a detail page.
pcweb/views/secondary_navbar.py New secondary navbar; menu_item helper is defined but never invoked; several rx.el.a components use the to= prop instead of the correct href=.
pcweb/utils/http.py New HTTP utility with a @once memoised singleton aiohttp.ClientSession; straightforward and correct.
pcweb/pages/templates/template_details/init.py Template detail page; injects FAQ JSON-LD schema and conditionally renders sections. No loading state guard — may briefly render empty content before active_template is populated.
pcweb/pages/templates/views/templates_grid.py Template card grid and sidebar filter UI; prefetches template on hover. rx.el.a link for the card uses href= correctly.
pcweb/route.py Migrates Route from reflex.base.Base to a plain @dataclasses.dataclass and adds on_load field support.
pcweb/templates/secondary_page.py New secondary_page decorator that wraps pages with the secondary navbar; cleanly threads on_load into the Route.

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser
    participant TemplatesState
    participant BuildBackend as Build Backend API

    User->>Browser: Navigate to /templates
    Browser->>TemplatesState: load_templates (on_load)
    alt _all_templates is empty
        TemplatesState->>BuildBackend: GET /api/v1/flexgen/templates/details
        BuildBackend-->>TemplatesState: list[dict]
        TemplatesState->>TemplatesState: _parse_templates_map()
        TemplatesState->>TemplatesState: _compute_tags() → self.tags
        TemplatesState->>TemplatesState: self.checked_tags = all tags
    else _all_templates already set
        TemplatesState->>TemplatesState: self.checked_tags = {t["label"] for t in self.tags}
        Note over TemplatesState: ⚠️ Bug: self.tags may be empty<br/>if arriving from detail page
    end
    TemplatesState-->>Browser: filtered_templates (computed var)
    User->>Browser: Hover over card
    Browser->>TemplatesState: prefetch_template(template_id)
    TemplatesState->>BuildBackend: GET /api/v1/flexgen/templates/{id}
    BuildBackend-->>TemplatesState: dict
    User->>Browser: Click card → /templates/[id]
    Browser->>TemplatesState: load_template_details (on_load)
    alt active_template.id == template_id
        TemplatesState->>TemplatesState: reuse cached template
    else
        TemplatesState->>BuildBackend: GET /api/v1/flexgen/templates/{id}
        BuildBackend-->>TemplatesState: dict
    end
    alt _all_templates is empty
        TemplatesState->>BuildBackend: GET /api/v1/flexgen/templates/details
        BuildBackend-->>TemplatesState: list[dict]
        Note over TemplatesState: ⚠️ Bug: tags NOT computed here
    end
    TemplatesState->>TemplatesState: compute related_templates (top 3 by tag overlap)
    TemplatesState-->>Browser: active_template, related_templates
Loading

Comments Outside Diff (4)

  1. pcweb/pages/templates/template_details/views/sidebar.py, line 596-613 (link)

    P0 "View Docs" and "Download Code" redirect to the same place as "Use This Template"

    All three buttons in links_section() share the identical on_click=TemplatesState.redirect_to_template(...) handler, meaning "View Docs" and "Download Code" both redirect users to the AI builder/template URL instead of the documentation or a download. This makes two of the three CTA buttons functionally broken.

    # "Use This Template" - correct
    on_click=TemplatesState.redirect_to_template(TemplatesState.active_template.id),
    
    # "View Docs" - should point to documentation, not redirect_to_template
    on_click=TemplatesState.redirect_to_template(TemplatesState.active_template.id),
    
    # "Download Code" - should point to download/source, not redirect_to_template
    on_click=TemplatesState.redirect_to_template(TemplatesState.active_template.id),

    These buttons need distinct event handlers that navigate to their respective destinations (e.g. the template's docs URL or a code download URL).

  2. pcweb/pages/templates/templates_state.py, line 1089-1103 (link)

    P1 self.tags never populated in load_template_details, causing broken filtering on templates page

    When load_template_details fetches all templates (the if not all_templates: branch), it stores them in self._all_templates but never computes or sets self.tags.

    If a user navigates directly to a template detail page (e.g. /templates/[id]) and then goes to /templates, load_templates detects self._all_templates is already populated and takes the early-return path:

    if self._all_templates:
        self.query = ""
        self.checked_tags = {t["label"] for t in self.tags}  # self.tags is []!
        return

    Because self.tags is still the default empty list, checked_tags is set to an empty set(). _matches_tags then returns False for every template that has at least one tag, so the grid renders completely empty.

    Fix: compute and store tags inside load_template_details whenever all templates are fetched:

    if not all_templates:
        all_data = await fetch_all_templates()
        all_templates = _parse_templates_map(all_data)
        tags = _compute_tags(list(all_templates.values()))  # add this
    
    all_templates[template_id] = template
    # ...
    async with self:
        self.active_template = template
        self.related_templates = related
        self._all_templates = all_templates
        if not self.tags:          # add this guard
            self.tags = tags       # add this
  3. pcweb/views/secondary_navbar.py, line 1608-1643 (link)

    P1 menu_item is defined but never called

    The menu_item function builds a full nav item with active-state highlighting logic, but navigation_menu() never calls it — all menu items are written inline and the function appears to be dead code. If active-state highlighting is desired for the secondary navbar links (Pricing, Docs), menu_item should be wired up; otherwise the function can be removed.

  4. pcweb/views/secondary_navbar.py, line 1629-1637 (link)

    P2 rx.el.a uses to= instead of href=

    rx.el.a is the raw HTML <a> element and expects href for navigation. to= is the prop used by rx.link (the styled Reflex component). Using to= on rx.el.a will pass an unrecognised attribute to the DOM and the link will silently fail to navigate.

    The same pattern appears in pcweb/pages/templates/template_details/views/header.py (line 72) and pcweb/pages/templates/template_details/views/others.py (line 15).

Last reviewed commit: "update shadows"

@Alek99 Alek99 self-requested a review March 18, 2026 17:21
@Alek99 Alek99 self-requested a review March 24, 2026 19:37
@Alek99 Alek99 merged commit 780027f into main Mar 24, 2026
10 checks passed
@Alek99 Alek99 deleted the carlos/templates-ui branch March 24, 2026 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants