feat(home): fix raw-markdown previews, rebalance dashboard grid, de-emphasize empty cards (LC-703) #669

Merged
longjacksonle merged 1 commit from feat/LC-703-home-dashboard-redesign into main 2026-08-13 04:38:23 +02:00

What

Redesigns the Home "Catch up" dashboard: fixes raw markdown leaking into message previews, rebalances the card grid, and de-emphasizes empty cards so populated ones lead.

Bug fix: raw markdown in previews

The Unread-channels card showed [📝 Call transcript saved](/transcripts/49) literally, because routes::home::preview_of flattened and truncated the raw body. Same "simplified render path drops markdown" class fixed earlier in the timeline and Saved views, on the dashboard's own path.

New shared helper views::markdown::plain_line(body, max) runs the real pulldown-cmark parser and emits clean plain text: [label](url) -> label, emphasis/heading/code markers dropped, whitespace collapsed, truncated with an ellipsis. Catch-up and Threads previews use it. The preview stays plain text (not a nested anchor - the whole row is already a deep-link to a different target). A body with no text (attachment/image/GIF only) falls back to a muted "📎 Attachment" label (new i18n key, en+es) instead of blank.

Deferred: per-type icons ("🖼 Image" vs "📎 File") need attachment metadata in the inbox/thread queries (data-layer change); a single generic label is used for now.

Layout and empty cards

  • Replaced the fixed sm:grid-cols-2 xl:grid-cols-3 grid (five cards stranded as an asymmetric 3+2 with big gaps) with an authored .lc-home-grid (auto-fill, minmax, align-items:start) so cards size to content and flow into balanced columns at any width, in a wider container.
  • Empty cards are de-emphasized and sort after populated ones via CSS order, so the cards carrying unread content lead.
  • Card headers show a count for populated sections; Catch-up rows carry a timestamp (<time datetime> from created_at) next to the count pill and rendered preview.
  • Authored CSS uses theme tokens only, so all four themes and both densities hold without a Tailwind rebuild (tailwind-built.css is gitignored).

Deferred: AI "catch me up" tie-in

The optional workspace-wide one-click AI summary is a new cross-room feature (the existing summarizer is per-room, routes::summary, and gated by the LC-702 AI audience), tracked as a follow-up rather than bundled here.

Testing

  • New plain_line unit tests: markdown link -> label, formatting stripped, single-line collapse, truncation, empty-body fallback.
  • Existing last_visited dashboard render test kept green.
  • Full suite: just test (195 binaries, 1640 tests), clippy standalone + saas, cargo fmt --check, i18n en/es parity.

Note on visual check: this is an SSO-gated web app, so an authenticated live screenshot needs a seeded DB + Bunyip login. Verified instead via Askama's compile-time template check, the authored token-only CSS, and the integration render test.

Closes LC-703.

🤖 Generated with Claude Code

https://claude.ai/code/session_016ufqbuN7mjyt4ms5NEygMy

## What Redesigns the Home "Catch up" dashboard: fixes raw markdown leaking into message previews, rebalances the card grid, and de-emphasizes empty cards so populated ones lead. ## Bug fix: raw markdown in previews The Unread-channels card showed `[📝 Call transcript saved](/transcripts/49)` literally, because `routes::home::preview_of` flattened and truncated the raw body. Same "simplified render path drops markdown" class fixed earlier in the timeline and Saved views, on the dashboard's own path. New shared helper `views::markdown::plain_line(body, max)` runs the real pulldown-cmark parser and emits clean plain text: `[label](url)` -> `label`, emphasis/heading/code markers dropped, whitespace collapsed, truncated with an ellipsis. Catch-up and Threads previews use it. The preview stays plain text (not a nested anchor - the whole row is already a deep-link to a different target). A body with no text (attachment/image/GIF only) falls back to a muted "📎 Attachment" label (new i18n key, en+es) instead of blank. Deferred: per-type icons ("🖼 Image" vs "📎 File") need attachment metadata in the inbox/thread queries (data-layer change); a single generic label is used for now. ## Layout and empty cards - Replaced the fixed `sm:grid-cols-2 xl:grid-cols-3` grid (five cards stranded as an asymmetric 3+2 with big gaps) with an authored `.lc-home-grid` (`auto-fill, minmax, align-items:start`) so cards size to content and flow into balanced columns at any width, in a wider container. - Empty cards are de-emphasized and sort after populated ones via CSS `order`, so the cards carrying unread content lead. - Card headers show a count for populated sections; Catch-up rows carry a timestamp (`<time datetime>` from `created_at`) next to the count pill and rendered preview. - Authored CSS uses theme tokens only, so all four themes and both densities hold without a Tailwind rebuild (`tailwind-built.css` is gitignored). ## Deferred: AI "catch me up" tie-in The optional workspace-wide one-click AI summary is a new cross-room feature (the existing summarizer is per-room, `routes::summary`, and gated by the LC-702 AI audience), tracked as a follow-up rather than bundled here. ## Testing - New `plain_line` unit tests: markdown link -> label, formatting stripped, single-line collapse, truncation, empty-body fallback. - Existing `last_visited` dashboard render test kept green. - Full suite: `just test` (195 binaries, 1640 tests), clippy standalone + saas, `cargo fmt --check`, i18n en/es parity. Note on visual check: this is an SSO-gated web app, so an authenticated live screenshot needs a seeded DB + Bunyip login. Verified instead via Askama's compile-time template check, the authored token-only CSS, and the integration render test. Closes LC-703. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_016ufqbuN7mjyt4ms5NEygMy
feat(home): fix raw-markdown previews, rebalance dashboard grid, de-emphasize empty cards (LC-703)
All checks were successful
check-secrets / Nosey parker (push) Successful in 5s
check-secrets / Kingfisher (push) Successful in 5s
check-secrets / TruffleHog (push) Successful in 5s
check-secrets / Nosey parker (pull_request) Successful in 3s
check-secrets / TruffleHog (pull_request) Successful in 5s
check-secrets / Kingfisher (pull_request) Successful in 6s
Check / clippy + fmt + tests (pull_request) Successful in 10m10s
Create release / Create release from merged PR (pull_request) Has been skipped
26572a7a53
The Home "Catch up" dashboard showed raw markdown in message previews (`[📝 Call transcript saved](/transcripts/49)` rendered literally), because routes::home::preview_of just flattened and truncated the raw body. This is the same "simplified render path drops markdown" class fixed earlier in the timeline and Saved views, reappearing on the dashboard's own preview path.

Adds a shared one-line preview helper, views::markdown::plain_line(body, max), that runs the real pulldown-cmark parser and emits clean plain text: a [label](url) link collapses to its label, emphasis/heading/code markers are dropped, whitespace collapses, and the result truncates at a char boundary with an ellipsis. The dashboard's Catch-up and Threads previews use it. Because each row is already a single deep-link, the preview stays plain text (not a nested anchor pointing at a different target). A message with no text body (attachment/image/GIF only) falls back to a muted "📎 Attachment" label (new i18n key, en+es) instead of rendering blank.

Layout: the fixed sm:grid-cols-2 xl:grid-cols-3 grid stranded five cards as an asymmetric 3+2 with large empty gaps. Replaced with an authored .lc-home-grid (auto-fill, minmax, align-items:start) so cards size to their content and flow into balanced columns at any width, in a wider container. Empty cards are de-emphasized and sort after populated ones via CSS order, so the cards that actually carry unread content lead; each card header now shows a count for populated sections, and Catch-up rows carry a timestamp (<time datetime> from the message created_at) alongside the count pill and rendered preview. Authored CSS uses theme tokens only, so all four themes and both densities hold without a Tailwind rebuild (tailwind-built.css is gitignored).

Deferred to follow-ups (noted on the ticket): per-type preview icons ("🖼 Image" vs "📎 File") need attachment metadata carried in the inbox/thread queries; and the optional workspace-wide "Catch me up" AI summary is a new cross-room feature (the existing summarizer is per-room) rather than a UI tweak.

Verification: just test (195 binaries, 1640 tests), clippy standalone + saas, cargo fmt --check, i18n en/es parity, new plain_line unit tests (link -> label, formatting stripped, single-line collapse, truncation, empty-body fallback), and the existing last_visited dashboard render test kept green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ufqbuN7mjyt4ms5NEygMy
longjacksonle scheduled this pull request to auto merge when all checks succeed 2026-08-13 04:30:40 +02:00
longjacksonle deleted branch feat/LC-703-home-dashboard-redesign 2026-08-13 04:38:24 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!669
No description provided.