feat: port dashboard home page from playground #76

Merged
forgejo_admin merged 2 commits from 69-port-dashboard-home into main 2026-03-27 21:55:02 +00:00

Summary

  • Replace old home page layout with playground's card-based dashboard design
  • Remove ~280 lines of scoped CSS that duplicated the design system
  • Use global CSS classes from app.css: note-card-row grid, project-grid, note-card--compact

Changes

  • src/routes/+page.svelte: Rewrote template to match playground index.html structure
    • "What changed recently?" title with home-title class
    • Recently Modified section using note-card with note-card-row grid (badge + title + time)
    • Projects section using project-grid and project-card with colored tree-dot
    • In Progress section using note-card--compact with board name context
    • Removed greeting logic, board progress bars, and all scoped styles
    • Added typeColor import for project dot colors and badgeClass helper

Test Plan

  • Visit / -- three sections visible: Recently Modified, Projects, In Progress
  • Note cards show colored left border matching note_type and badge + title + time grid
  • Project cards show colored dot and relative time
  • In-progress items show badge, title, and board name in compact row
  • Responsive: mobile (375px) single-column project grid, desktop (600px+) two-column
  • DORA Dashboard at /dashboard is unchanged
  • npm run build passes
  • npm run check passes with 0 errors

Review Checklist

  • Passed automated review-fix loop
  • No secrets committed
  • No unnecessary file changes
  • Commit messages are descriptive
  • forgejo_admin/pal-e-app #69 -- the Forgejo issue this PR implements
  • pal-e-app -- the project this work belongs to

Closes #69

## Summary - Replace old home page layout with playground's card-based dashboard design - Remove ~280 lines of scoped CSS that duplicated the design system - Use global CSS classes from app.css: note-card-row grid, project-grid, note-card--compact ## Changes - `src/routes/+page.svelte`: Rewrote template to match playground `index.html` structure - "What changed recently?" title with `home-title` class - Recently Modified section using `note-card` with `note-card-row` grid (badge + title + time) - Projects section using `project-grid` and `project-card` with colored `tree-dot` - In Progress section using `note-card--compact` with board name context - Removed greeting logic, board progress bars, and all scoped styles - Added `typeColor` import for project dot colors and `badgeClass` helper ## Test Plan - [ ] Visit `/` -- three sections visible: Recently Modified, Projects, In Progress - [ ] Note cards show colored left border matching note_type and badge + title + time grid - [ ] Project cards show colored dot and relative time - [ ] In-progress items show badge, title, and board name in compact row - [ ] Responsive: mobile (375px) single-column project grid, desktop (600px+) two-column - [ ] DORA Dashboard at `/dashboard` is unchanged - [ ] `npm run build` passes - [ ] `npm run check` passes with 0 errors ## Review Checklist - [x] Passed automated review-fix loop - [x] No secrets committed - [x] No unnecessary file changes - [x] Commit messages are descriptive ## Related Notes - `forgejo_admin/pal-e-app #69` -- the Forgejo issue this PR implements - `pal-e-app` -- the project this work belongs to Closes #69
feat: port dashboard home page from playground to match design system
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
b38ab89b2c
Replace the old home page layout (greeting, section-headers, custom
scoped styles) with the playground's card-based dashboard design.
Uses global CSS classes from app.css: note-card with note-card-row grid,
project-grid with project-card, and note-card--compact for in-progress
items. Removes ~280 lines of scoped CSS that duplicated or conflicted
with the design system.

Closes #69

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Owner

QA Review -- PR #76

What looks good

  • Single file change, 83 additions / 368 deletions -- clean and focused
  • Template structure matches playground index.html literally: content--home, home-title, home-section with sidebar-label, note-card-row grid layout
  • All scoped CSS removed in favor of global app.css classes -- no style duplication
  • Data fetching logic preserved unchanged (same onMount, same API calls, same error handling)
  • badgeClass helper cleanly maps note_type to CSS badge class
  • typeColor import wired for project card dots
  • Build passes, svelte-check passes with 0 errors

Nits

  1. Dead code: boards fetch -- listBoards() is still called in onMount and the boards state variable is declared, but neither is used in the template anymore (Board Progress section was removed). The listBoardActivity call is still needed for in-progress items, but listBoards and boards are now dead weight. Should be cleaned up.

  2. PRIVATE badge dropped -- The old page showed a red PRIVATE badge for is_public === false notes. The playground omits this. Intentional per the port spec (copy playground literally), but worth confirming this is desired since authenticated users will see private notes without any visual indicator.

VERDICT: APPROVE with nits

The dead boards fetch is minor cleanup. The PRIVATE badge drop follows the playground spec. Both can be addressed in a follow-up if desired.

## QA Review -- PR #76 ### What looks good - Single file change, 83 additions / 368 deletions -- clean and focused - Template structure matches playground `index.html` literally: `content--home`, `home-title`, `home-section` with `sidebar-label`, `note-card-row` grid layout - All scoped CSS removed in favor of global `app.css` classes -- no style duplication - Data fetching logic preserved unchanged (same `onMount`, same API calls, same error handling) - `badgeClass` helper cleanly maps `note_type` to CSS badge class - `typeColor` import wired for project card dots - Build passes, `svelte-check` passes with 0 errors ### Nits 1. **Dead code: `boards` fetch** -- `listBoards()` is still called in `onMount` and the `boards` state variable is declared, but neither is used in the template anymore (Board Progress section was removed). The `listBoardActivity` call is still needed for in-progress items, but `listBoards` and `boards` are now dead weight. Should be cleaned up. 2. **PRIVATE badge dropped** -- The old page showed a red `PRIVATE` badge for `is_public === false` notes. The playground omits this. Intentional per the port spec (copy playground literally), but worth confirming this is desired since authenticated users will see private notes without any visual indicator. ### VERDICT: APPROVE with nits The dead `boards` fetch is minor cleanup. The PRIVATE badge drop follows the playground spec. Both can be addressed in a follow-up if desired.
fix: remove unused boards state variable from home page
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
0e75b7fcea
Clean up the dead `boards` state variable that was left over after
removing the Board Progress section. The `listBoards` call is still
needed to build `boardMap` for in-progress item board name resolution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Owner

Fixed nit #1: removed unused boards state variable in 0e75b7f. The listBoards call is retained since it's needed to build boardMap for in-progress item board name resolution.

Nit #2 (PRIVATE badge dropped) is intentional per the playground port spec -- no action needed.

Fixed nit #1: removed unused `boards` state variable in `0e75b7f`. The `listBoards` call is retained since it's needed to build `boardMap` for in-progress item board name resolution. Nit #2 (PRIVATE badge dropped) is intentional per the playground port spec -- no action needed.
forgejo_admin deleted branch 69-port-dashboard-home 2026-03-27 21:55:02 +00:00
Author
Owner

PR #76 Review

DOMAIN REVIEW

Tech stack: SvelteKit 5 (runes mode), TypeScript, pure CSS design system (no Tailwind).

What the PR does: Replaces the old home page layout (greeting, list-based sections, board progress bars, ~280 lines of scoped CSS) with the playground's card-based dashboard design that uses global CSS classes from app.css. Single file changed: src/routes/+page.svelte. Net -292 lines.

CSS class audit -- all global classes referenced in the new template are properly defined in src/app.css:

  • content--home (line 527), home-title (line 532), home-section (not found explicitly -- see nit below)
  • sidebar-label (line 236), note-list (line 552), note-card (line 553)
  • note-card-row (line 583), note-card-title (line 571), meta-time (line 314)
  • badge / badge--{type} (lines 318-340), project-grid (line 606), project-card (line 611)
  • tree-dot (line 266), project-card-name (line 621), project-card-stats (line 629)
  • note-card--compact (line 573), note-card-project (line 570), view-all (line 543)
  • empty-state (line 772), data-type attribute selectors (lines 564-568)

TypeScript correctness:

  • typeColor import from $lib/colors is valid -- function exists at src/lib/colors.ts:39
  • badgeClass helper correctly handles null note_type with fallback to bare badge class
  • BoardItem.item_type is typed as string (not nullable) in api-client.ts:47 -- safe to pass directly to badgeClass, though badgeClass accepts string | null which is wider than needed here (not a bug, just imprecise)
  • Unused boards state variable correctly removed; bds local still used for boardMap construction

Accessibility:

  • Section labels use <div class="sidebar-label"> instead of semantic heading elements (<h2>, <h3>). Screen readers will not recognize "Recently Modified", "Projects", and "In Progress" as section headings. The old version used <h2> elements. This is a regression for screen reader navigation.
  • The <section> elements are good semantic structure, but without heading children they lose their landmark value per WCAG.
  • Board progress bars with role="progressbar" and full ARIA attributes were removed. This was intentional (the feature is gone), so no regression there.

Component patterns:

  • Good: all cards are <a> elements (keyboard-navigable, focusable)
  • Good: data-type attribute on note cards enables CSS-driven left-border coloring
  • Good: in-progress items link to note page when note_slug exists, falls back to board page

BLOCKERS

1. E2E tests will fail -- existing tests not updated (BLOCKER: new functionality with broken test coverage)

e2e/home.spec.ts contains 7 tests that reference selectors and elements removed or renamed by this PR:

  • Line 19: waitForSelector('.greeting') -- .greeting class removed
  • Line 23: locator('.greeting') -- removed
  • Line 48: getByRole('heading', { name: 'Recently Updated', level: 2 }) -- renamed to "Recently Modified" and changed from <h2> to <div class="sidebar-label">
  • Line 54: getByRole('heading', { name: 'In Progress', level: 2 }) -- changed from <h2> to <div>
  • Line 60: getByRole('heading', { name: 'Projects', level: 2 }) -- changed from <h2> to <div>
  • Line 63: locator('.project-list') -- class renamed to .project-grid
  • Lines 66-71: Board Progress section tests -- entire section removed

Every test in the home page suite will fail. The E2E file must be updated to match the new DOM structure. Per QA policy, this is a blocker, not a nit.

NITS

  1. home-section class not defined in app.css: The template uses class="home-section" on three <section> elements, but I could not find a .home-section rule in src/app.css. If this class has no styles, it is dead markup. If styles are intended, they are missing. Either way, worth confirming.

  2. Accessibility: section labels should be headings: <div class="sidebar-label">Recently Modified</div> should be <h2 class="sidebar-label">Recently Modified</h2> (or <h3> depending on hierarchy). This preserves screen reader navigation and WCAG section landmark semantics at zero visual cost. The sidebar-label CSS class does not rely on the element being a <div>.

  3. relativeTime is a candidate for extraction: This utility function is defined inline in +page.svelte. As more pages port from the playground, this pattern will likely be needed elsewhere. Consider extracting to $lib/utils.ts proactively.

  4. Hardcoded 'project-page' in typeColor call: style="background: {typeColor('project-page')};" on line ~88 of the new code hardcodes the type string. All projects get the same dot color regardless of any future type differentiation. This matches the playground design but is worth noting for future flexibility.

  5. badgeClass parameter type is wider than needed for item_type: BoardItem.item_type is string (non-nullable), but badgeClass accepts string | null. Not a bug, but the null branch is unreachable when called with item.item_type.

SOP COMPLIANCE

  • Branch named after issue -- Unverifiable (PR merged, head ref shows refs/pull/76/head; branch likely deleted)
  • PR body follows template -- Summary, Changes, Test Plan, Review Checklist, Related Notes all present
  • Related references parent issue -- forgejo_admin/pal-e-app #69 referenced, Closes #69 included
  • No secrets committed -- single .svelte file, no credentials
  • No unnecessary file changes -- exactly 1 file changed, tightly scoped to the home page port
  • Commit messages are descriptive -- feat: port dashboard home page from playground

PROCESS OBSERVATIONS

  • Change Failure Risk: HIGH -- The E2E test suite for the home page will fail on every selector. If CI runs E2E tests, this merge would have been caught. If CI does not run E2E, this is a silent regression that will block future PRs that do run E2E.
  • Deployment Frequency: This is part of a larger playground port series (PRs #75-#81). The pattern of porting pages one-at-a-time is good for incremental delivery, but each port must update its corresponding E2E tests in the same PR.
  • Test Plan gap: The PR body's Test Plan lists manual checks but does not mention E2E test updates. The review-fix loop should have caught the E2E breakage.

VERDICT: NOT APPROVED

The E2E test suite at e2e/home.spec.ts references DOM selectors and elements that this PR removes or renames. All 7 tests in the home page suite will fail. The test file must be updated to match the new DOM structure before this PR can be approved.

## PR #76 Review ### DOMAIN REVIEW **Tech stack**: SvelteKit 5 (runes mode), TypeScript, pure CSS design system (no Tailwind). **What the PR does**: Replaces the old home page layout (greeting, list-based sections, board progress bars, ~280 lines of scoped CSS) with the playground's card-based dashboard design that uses global CSS classes from `app.css`. Single file changed: `src/routes/+page.svelte`. Net -292 lines. **CSS class audit** -- all global classes referenced in the new template are properly defined in `src/app.css`: - `content--home` (line 527), `home-title` (line 532), `home-section` (not found explicitly -- see nit below) - `sidebar-label` (line 236), `note-list` (line 552), `note-card` (line 553) - `note-card-row` (line 583), `note-card-title` (line 571), `meta-time` (line 314) - `badge` / `badge--{type}` (lines 318-340), `project-grid` (line 606), `project-card` (line 611) - `tree-dot` (line 266), `project-card-name` (line 621), `project-card-stats` (line 629) - `note-card--compact` (line 573), `note-card-project` (line 570), `view-all` (line 543) - `empty-state` (line 772), `data-type` attribute selectors (lines 564-568) **TypeScript correctness**: - `typeColor` import from `$lib/colors` is valid -- function exists at `src/lib/colors.ts:39` - `badgeClass` helper correctly handles `null` note_type with fallback to bare `badge` class - `BoardItem.item_type` is typed as `string` (not nullable) in `api-client.ts:47` -- safe to pass directly to `badgeClass`, though `badgeClass` accepts `string | null` which is wider than needed here (not a bug, just imprecise) - Unused `boards` state variable correctly removed; `bds` local still used for `boardMap` construction **Accessibility**: - Section labels use `<div class="sidebar-label">` instead of semantic heading elements (`<h2>`, `<h3>`). Screen readers will not recognize "Recently Modified", "Projects", and "In Progress" as section headings. The old version used `<h2>` elements. This is a regression for screen reader navigation. - The `<section>` elements are good semantic structure, but without heading children they lose their landmark value per WCAG. - Board progress bars with `role="progressbar"` and full ARIA attributes were removed. This was intentional (the feature is gone), so no regression there. **Component patterns**: - Good: all cards are `<a>` elements (keyboard-navigable, focusable) - Good: `data-type` attribute on note cards enables CSS-driven left-border coloring - Good: in-progress items link to note page when `note_slug` exists, falls back to board page ### BLOCKERS **1. E2E tests will fail -- existing tests not updated (BLOCKER: new functionality with broken test coverage)** `e2e/home.spec.ts` contains 7 tests that reference selectors and elements removed or renamed by this PR: - Line 19: `waitForSelector('.greeting')` -- `.greeting` class removed - Line 23: `locator('.greeting')` -- removed - Line 48: `getByRole('heading', { name: 'Recently Updated', level: 2 })` -- renamed to "Recently Modified" and changed from `<h2>` to `<div class="sidebar-label">` - Line 54: `getByRole('heading', { name: 'In Progress', level: 2 })` -- changed from `<h2>` to `<div>` - Line 60: `getByRole('heading', { name: 'Projects', level: 2 })` -- changed from `<h2>` to `<div>` - Line 63: `locator('.project-list')` -- class renamed to `.project-grid` - Lines 66-71: Board Progress section tests -- entire section removed Every test in the home page suite will fail. The E2E file must be updated to match the new DOM structure. Per QA policy, this is a blocker, not a nit. ### NITS 1. **`home-section` class not defined in app.css**: The template uses `class="home-section"` on three `<section>` elements, but I could not find a `.home-section` rule in `src/app.css`. If this class has no styles, it is dead markup. If styles are intended, they are missing. Either way, worth confirming. 2. **Accessibility: section labels should be headings**: `<div class="sidebar-label">Recently Modified</div>` should be `<h2 class="sidebar-label">Recently Modified</h2>` (or `<h3>` depending on hierarchy). This preserves screen reader navigation and WCAG section landmark semantics at zero visual cost. The `sidebar-label` CSS class does not rely on the element being a `<div>`. 3. **`relativeTime` is a candidate for extraction**: This utility function is defined inline in `+page.svelte`. As more pages port from the playground, this pattern will likely be needed elsewhere. Consider extracting to `$lib/utils.ts` proactively. 4. **Hardcoded `'project-page'` in typeColor call**: `style="background: {typeColor('project-page')};"` on line ~88 of the new code hardcodes the type string. All projects get the same dot color regardless of any future type differentiation. This matches the playground design but is worth noting for future flexibility. 5. **`badgeClass` parameter type is wider than needed for `item_type`**: `BoardItem.item_type` is `string` (non-nullable), but `badgeClass` accepts `string | null`. Not a bug, but the null branch is unreachable when called with `item.item_type`. ### SOP COMPLIANCE - [ ] Branch named after issue -- **Unverifiable** (PR merged, head ref shows `refs/pull/76/head`; branch likely deleted) - [x] PR body follows template -- Summary, Changes, Test Plan, Review Checklist, Related Notes all present - [x] Related references parent issue -- `forgejo_admin/pal-e-app #69` referenced, `Closes #69` included - [x] No secrets committed -- single `.svelte` file, no credentials - [x] No unnecessary file changes -- exactly 1 file changed, tightly scoped to the home page port - [x] Commit messages are descriptive -- `feat: port dashboard home page from playground` ### PROCESS OBSERVATIONS - **Change Failure Risk: HIGH** -- The E2E test suite for the home page will fail on every selector. If CI runs E2E tests, this merge would have been caught. If CI does not run E2E, this is a silent regression that will block future PRs that do run E2E. - **Deployment Frequency**: This is part of a larger playground port series (PRs #75-#81). The pattern of porting pages one-at-a-time is good for incremental delivery, but each port must update its corresponding E2E tests in the same PR. - **Test Plan gap**: The PR body's Test Plan lists manual checks but does not mention E2E test updates. The review-fix loop should have caught the E2E breakage. ### VERDICT: NOT APPROVED The E2E test suite at `e2e/home.spec.ts` references DOM selectors and elements that this PR removes or renames. All 7 tests in the home page suite will fail. The test file must be updated to match the new DOM structure before this PR can be approved.
Sign in to join this conversation.
No reviewers
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
forgejo_admin/pal-e-docs-app!76
No description provided.