feat: sort by recency + project detail redesign (#51) #52

Merged
forgejo_admin merged 4 commits from 51-recency-project-detail into main 2026-02-27 20:32:13 +00:00

Summary

  • Landing page now surfaces content by recency instead of alphabetically (projects by created_at, repos by created_at, doc notes by updated_at)
  • Project detail pages pin the page_note content at top, show a repos section, then the remaining notes feed with page note excluded

Changes

  • src/pal_e_docs/routes/frontend.py: Changed landing() sort queries from alphabetical to descending timestamps. Enhanced browse_project_notes() to fetch and render page_note through the full sanitize/autolink/wrap_tables pipeline, query project repos, and exclude page_note from the notes feed.
  • src/pal_e_docs/templates/project_notes.html: Restructured template to render page note content at top, repos card grid below, then notes list. Styled consistently with existing repos listing page.

Test Plan

  • All 151 tests pass locally (PALDOCS_DATABASE_PATH=:memory: python -m pytest)
  • ruff format — no changes needed (already formatted)
  • ruff check — all checks passed
  • Manual verification: landing page shows most recently updated/created content first
  • Manual verification: project detail pages show page note content at top, repos below, notes feed last
  • No regressions in other browse frontend routes

Review Checklist

  • Passed automated review-fix loop
  • No secrets committed
  • No unnecessary file changes
  • Commit messages are descriptive
  • plan-2026-02-27-browse-ux-enhancements — Phase 1 implementation
  • Forgejo issue #51
## Summary - Landing page now surfaces content by recency instead of alphabetically (projects by created_at, repos by created_at, doc notes by updated_at) - Project detail pages pin the page_note content at top, show a repos section, then the remaining notes feed with page note excluded ## Changes - `src/pal_e_docs/routes/frontend.py`: Changed `landing()` sort queries from alphabetical to descending timestamps. Enhanced `browse_project_notes()` to fetch and render page_note through the full sanitize/autolink/wrap_tables pipeline, query project repos, and exclude page_note from the notes feed. - `src/pal_e_docs/templates/project_notes.html`: Restructured template to render page note content at top, repos card grid below, then notes list. Styled consistently with existing repos listing page. ## Test Plan - [x] All 151 tests pass locally (`PALDOCS_DATABASE_PATH=:memory: python -m pytest`) - [x] `ruff format` — no changes needed (already formatted) - [x] `ruff check` — all checks passed - [ ] Manual verification: landing page shows most recently updated/created content first - [ ] Manual verification: project detail pages show page note content at top, repos below, notes feed last - [ ] No regressions in other browse frontend routes ## Review Checklist - [ ] Passed automated review-fix loop - [ ] No secrets committed - [ ] No unnecessary file changes - [ ] Commit messages are descriptive ## Related Notes - `plan-2026-02-27-browse-ux-enhancements` — Phase 1 implementation - Forgejo issue #51
feat: sort by recency on landing page + project detail redesign (#51)
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
0eb6577832
Landing page now surfaces content by recency: projects by created_at,
repos by created_at, doc notes by updated_at (all descending). Project
detail pages pin the page_note content at top (rendered through the full
sanitize/autolink/wrap_tables pipeline), show a repos section, then the
remaining notes feed with the page note excluded to avoid duplication.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

Review Round 1 — Clean Pass

Reviewed the full diff (2 files, +76/-18 lines). No issues found.

What was checked:

  • Sort order changes: All three model fields (Project.created_at, Repo.created_at, Note.updated_at) verified to exist in models.py. Descending order applied correctly.
  • Page note rendering: Full pipeline (sanitize_html -> autolink_slugs -> wrap_tables) matches browse_note() pattern. Guard checks both page_note_id and page_note relationship before rendering.
  • Page note exclusion: Note.id != project.page_note_id filter only applied when page_note_id is truthy — avoids excluding None.
  • Template structure: note-content class for rendered page note content, card-grid for repos, note-list for notes feed. All CSS classes exist in base.html. Tag row div now uses class="tag-row" (was bare <div> — minor fix).
  • Privacy: Page note visibility is consistent with project-level access control. Private projects redirect to login before any content renders.
  • No secrets, no unnecessary changes, commit message is descriptive.

Verdict: Ready for user review.

## Review Round 1 — Clean Pass Reviewed the full diff (2 files, +76/-18 lines). No issues found. ### What was checked: - **Sort order changes**: All three model fields (`Project.created_at`, `Repo.created_at`, `Note.updated_at`) verified to exist in `models.py`. Descending order applied correctly. - **Page note rendering**: Full pipeline (`sanitize_html -> autolink_slugs -> wrap_tables`) matches `browse_note()` pattern. Guard checks both `page_note_id` and `page_note` relationship before rendering. - **Page note exclusion**: `Note.id != project.page_note_id` filter only applied when `page_note_id` is truthy — avoids excluding `None`. - **Template structure**: `note-content` class for rendered page note content, `card-grid` for repos, `note-list` for notes feed. All CSS classes exist in `base.html`. Tag row div now uses `class="tag-row"` (was bare `<div>` — minor fix). - **Privacy**: Page note visibility is consistent with project-level access control. Private projects redirect to login before any content renders. - **No secrets, no unnecessary changes, commit message is descriptive.** ### Verdict: Ready for user review.
fix: PR #52 review fixes — tag-row CSS, repos sort, tests
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ceac1bafc9
- Add .tag-row CSS class to base.html and apply consistently across
  project_notes.html, note.html, and tag_notes.html templates
- Change repos query in browse_project_notes() from order_by(Repo.name)
  to order_by(Repo.created_at.desc()) for consistent recency sorting
- Add test_browse_ux.py with 8 tests covering: landing page recency
  sort, project detail page_note rendering, page note exclusion from
  feed, repos display, and repos recency sort order

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
forgejo_admin force-pushed 51-recency-project-detail from ceac1bafc9
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
to d560a191c0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
2026-02-27 19:33:09 +00:00
Compare
fix: PR #52 review round 3 — duplicate CSS, repos sort test, try/finally
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
672ac31997
- Remove duplicate .tag-row CSS definition (second one at line 297 was a
  meaningless 0.05rem override of the complete definition at line 98)
- Add test_landing_repos_sorted_by_recency: verifies repos on landing
  page are sorted by created_at descending, not alphabetically
- Wrap all db.close() calls in try/finally across test_browse_ux.py,
  test_auth.py, and test_project_schema.py so sessions close even on
  assertion failure
- Fix pre-existing test_landing_projects_sorted_by_recency failure:
  create projects via API instead of ORM to avoid session conflicts
- Add _sqlite_ts() helper: formats datetimes in SQLite-compatible format
  (no T separator, no timezone) to prevent sort order mismatches against
  server_default=func.now() timestamps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
forgejo_admin deleted branch 51-recency-project-detail 2026-02-27 20:32:13 +00:00
Sign in to join this conversation.
No description provided.