Skip to content

Story #2560: implement the unavailable library page UI - #2578

Open
ycanales wants to merge 8 commits into
julia/improve-library-subpage-layoutfrom
cy/2560-unavailable-library-page
Open

Story #2560: implement the unavailable library page UI#2578
ycanales wants to merge 8 commits into
julia/improve-library-subpage-layoutfrom
cy/2560-unavailable-library-page

Conversation

@ycanales

@ycanales ycanales commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Issue: #2560

Stacked on #2556 (julia/improve-library-subpage-layout), which added the placeholder this replaces. Retarget to develop once #2556 merges. Trying out the Github stacked layout thing.

Summary & Context

Replaces the inline placeholder on the v3 library subpage with the designed empty state for a library that has no version in the selected Boost release: headline, a sentence naming the library and versions, a "Switch to ..." CTA and the bookshelf illustration.

Changes

View (libraries/views.py)

  • Add LibraryDetail.get_missing_version_context(), which builds the sentence and the CTA label/URL. The sentence has two forms: past a library's last release, "The last release which included X was Y"; before its first, "The first release of X library was version Y". The two are selected by a numeric version comparison (cleaned_version_parts_int).
  • The "first release" form excludes betas. Library.first_boost_version spans them, so Boost.Decimal was announcing "version 1.91.0.beta1".
  • get_v3_context_data() now returns early for the missing-version case, so the subpage's contributor, quick-start, dependency and benchmark context is no longer computed for a page that renders none of it.

Hero component (templates/v3/includes/_hero_library.html)

  • Add optional cta_label / cta_url / cta_icon_name, rendered through the existing _button_hero.html inside .hero__actions. The block collapses when they are absent, so every existing caller is unchanged.

Empty state template (templates/v3/includes/_library_version_unavailable.html, new)

  • Wires the hero to the empty-state copy and to the existing empty-library-light/dark.png illustration already shipped for the library-list empty state. No new asset: it is the same artwork as the Figma frame.

Styles (static/css/v3/heros.css)

  • Older version warning bar below Nav bar, as shown in Figma.
  • New hero--library-unavailable variant: page surface instead of the hero's accent yellow, Figma's 32px rhythm between headline, sentence and CTA, and a bottom-flush illustration.
  • The block's fixed height becomes a min-height for this variant only, since the empty state's copy is longer than a library hero's and would otherwise overflow the CTA onto the version alert in the tablet band.
  • The illustration ships on an opaque plate (white in the light export, black in the dark one), so it is blended into the surface with multiply / screen. That needs a matching background on .hero__image, because .hero__block opens a stacking context and closes the blending group above the section background.

Tests (libraries/tests/test_views.py)

  • Three tests: the empty-state context, the removed-library CTA, and the fallback to the "first release" sentence on releases older than the library.
  • Pin the legacy v2 test_library_detail_missing_version with override_flag("v3", active=False). It was passing only on ambient flag state and flipped to the v3 template whenever the cached waffle flag was warm.

‼️ Risks & Considerations ‼️

  • ‼️ The CTA does not always point at "latest". For a library removed from Boost, the button targets the library's last release and the label changes from "Switch to latest (1.91.0)" to "Switch to 1.86.0". Compatibility and Signals are the only two on the site.
  • Library.first_boost_version still spans betas, and it feeds the hero's "Added in {version}" chip, so a populated Boost.Decimal page reads "Added in 1.91.0.beta1". Fixing the shared property is out of scope here, and the chip and this empty state never render on the same page.
  • Rejected: a standalone empty-state template. Reusing _hero_library.html costs three optional variables and keeps the responsive type ladder, the theme-aware image swap and the version alert in one place. A separate template would have duplicated all three and drifted from the other heroes.
  • Rejected: building the sentence in the template. It reads as static copy, but it is two different sentences chosen by a numeric version comparison.

Peer-Testing Guidelines

Every URL below is real Boost history and works on any environment with the catalogue imported.

  1. (Local only.) If the page renders the legacy layout, the cached v3 waffle flag is stale:

    docker compose exec redis redis-cli FLUSHALL
    
  2. Library newer than the release. Visit /library/1.85.0/decimal/. Expect the headline, a sentence naming both versions, a "Switch to latest (1.91.0)" button naming the current release, and the illustration on the page surface rather than the yellow hero background. The button should land on /library/latest/decimal/.

  3. Library removed from Boost. Visit /library/latest/compatibility/. The sentence should read "The last release which included Boost.Compatibility was 1.86.0", and the button "Switch to 1.86.0", linking to /library/1.86.0/compatibility/ rather than back to latest.

  4. Responsive and themes. Resize through 1440 / 768 / 375 in both themes. The illustration should have no visible panel edge behind it in either theme, and at 768 the CTA must stay clear of the version alert banner.

  5. No regression on a populated subpage. Visit /library/latest/decimal/ and confirm the hero still shows the tag row, the Documentation / Source code / Slack / GitHub Issues links and the Master/Develop buttons, with no CTA button. Those branch buttons should be absent from the empty state.

More URLs, covering both cases:

URL Why it is empty Expected CTA
/library/1.85.0/decimal/ added in 1.91.0 Switch to latest (1.91.0)
/library/1.80.0/cobalt/ added in 1.84.0 Switch to latest (1.91.0)
/library/1.80.0/mysql/ added in 1.82.0 Switch to latest (1.91.0)
/library/latest/compatibility/ removed in 1.87.0 Switch to 1.86.0
/library/latest/signals/ removed in 1.69.0 Switch to 1.68.0

To find more of the first kind without database access: open any library at latest and read the "Added in {version}" chip, then pick an older release from the version dropdown. The second kind needs no searching, since Compatibility and Signals are the only two.

Screenshots

Screenshot Notes
image Desktop 1440, light.
image Desktop 1440, dark. Dark illustration export, no visible plate behind it.
image Boost.Compatibility at latest: the CTA reads "Switch to 1.86.0", the library's last release, instead of pointing back at latest. Update: Now it reads "The last release which included Boost.Compatibility was 1.86.0"

Self-review Checklist

  • Tag at least one team member from each team to review this PR
  • Link this PR to the related GitHub Project ticket

Frontend

  • UI implementation matches Figma design
  • Tested in light and dark mode
  • Responsive / mobile verified (1440 / 768 / 375)
  • Accessibility checked: <h1> carries the message, the CTA is a plain focusable link, the illustration is decorative (alt="")
  • Ensure design tokens are used for colors, spacing, typography, etc. No hardcoded values
  • Test without JavaScript (the page is static markup)
  • No console errors or warnings

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 514f21b5-883a-4a8c-a1f5-8632c6ce8dac

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ycanales
ycanales force-pushed the cy/2560-unavailable-library-page branch from e674ea5 to 3dcd88b Compare August 6, 2026 15:48
@ycanales ycanales linked an issue Aug 7, 2026 that may be closed by this pull request
@ycanales
ycanales force-pushed the cy/2560-unavailable-library-page branch from 3dcd88b to bb671ce Compare August 12, 2026 15:29

@julhoang julhoang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ycanales , thanks so much for tackling hero refactor to adjust the version banner placement!

Currently the banner adds 40px to the overall height of the banner, whereas our intention is actually to have the banner sit on top of the hero (position: absolute), so that it doesn't cause a layout shift when user dismisses it. Would you mind addressing this? 🙏

Comment thread libraries/views.py Outdated
Comment thread libraries/views.py Outdated
Comment thread static/css/v3/heros.css
@ycanales
ycanales force-pushed the cy/2560-unavailable-library-page branch from b35f7c4 to 2cb6776 Compare August 14, 2026 20:52
@ycanales
ycanales requested a review from julhoang August 14, 2026 20:52

@julhoang julhoang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me, thank you for all the updates @ycanales ! Just 1 more ask - would you mind adjusting the template to push the footer to the bottom of the screen? Pre-approving now 😄

@ycanales

Copy link
Copy Markdown
Collaborator Author

Thanks @julhoang ! I applied the same fix I did for PR #2536:
image

@jlchilders11 jlchilders11 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, responds to all sizes and provides expected output on the scenarios!

Replaces the placeholder on the v3 library subpage with the designed empty
state: headline, a sentence naming the library and versions, a "Switch to ..."
CTA and the bookshelf illustration, built on the shared library hero.

- Add optional cta_label/cta_url/cta_icon_name to _hero_library.html, rendered
  through the existing hero button component
- Add a hero--library-unavailable variant: page surface instead of the accent
  background, Figma's 32px content rhythm, bottom-flush illustration blended
  into the surface, and a min-height so the longer copy can't overflow the
  version alert in the tablet band
- Build the sentence and CTA in the view, since both branch on data: a library
  with no releases has no "first release" clause and nowhere to switch to, and
  a library dropped from Boost points at its last release rather than latest
- Skip the subpage card context entirely when the version is missing
Drop the parts that restate what the declarations already show and keep
the reasons that are not visible from the code: the --header-height
resolution trap, the stacking context that closes the blending group,
and why the block's fixed height becomes a floor.
The first-release lookup only feeds the 'elif' sentence, so evaluate it
there instead of unconditionally. Its filters were also a copy of the
newest-release lookup's, so both now derive from one queryset.
…state

master and develop carry no version number, so the numeric comparison
placed them before the library's first release and the page offered the
'first release' sentence for a library that had left Boost. They are
branch heads, so they sort after every release instead.

Also word them as 'the develop branch' rather than 'Boost develop'.
The alert sat in the hero's column, so showing or dismissing it moved
everything below by its height plus the section gap. It now overlays the
slack the hero already leaves under the header, and .hero__block keeps
its own clearance, so the hero is the same height either way.

Below 767px there is no such slack and the message can wrap to three
lines, so the alert stays in flow there rather than cover the heading.
@ycanales
ycanales force-pushed the cy/2560-unavailable-library-page branch from b2a0d70 to efa1448 Compare August 21, 2026 14:27
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.

Webpage UI: Unavailable Library page

3 participants