Skip to content

Commit 218ba48

Browse files
committed
Filtering on rating
1 parent e58e8f7 commit 218ba48

File tree

28 files changed

+240
-38
lines changed

28 files changed

+240
-38
lines changed

docs/specs/4-architecture/features/006-photo-rating-filter/spec.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
| Field | Value |
44
|-------|-------|
5-
| Status | Draft |
6-
| Last updated | 2026-01-03 |
5+
| Status | Implemented |
6+
| Last updated | 2026-01-14 |
77
| Owners | Agent |
88
| Linked plan | `docs/specs/4-architecture/features/006-photo-rating-filter/plan.md` |
99
| Linked tasks | `docs/specs/4-architecture/features/006-photo-rating-filter/tasks.md` |

docs/specs/4-architecture/features/006-photo-rating-filter/tasks.md

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Feature 006 Tasks – Photo Star Rating Filter
22

3-
_Status: Draft_
4-
_Last updated: 2026-01-03_
3+
_Status: Implemented_
4+
_Last updated: 2026-01-14_
55

66
> Keep this checklist aligned with the feature plan increments. Stage tests before implementation, record verification commands beside each task, and prefer bite-sized entries (≤90 minutes).
77
> **Mark tasks `[x]` immediately** after each one passes verification—do not batch completions. Update the roadmap status when all tasks are done.
@@ -12,31 +12,31 @@ _Last updated: 2026-01-03_
1212

1313
### Increment I1 – PhotosState Store Modifications
1414

15-
- [ ] T-006-01 – Locate and read PhotosState.ts store structure (FR-006-04).
15+
- [x] T-006-01 – Locate and read PhotosState.ts store structure (FR-006-04).
1616
_Intent:_ Understand existing PhotosState store to plan modifications.
1717
_Verification commands:_
1818
- File read and structure understood
1919
_Notes:_ Verify store exists at expected location, note existing properties and patterns.
2020

21-
- [ ] T-006-02 – Add photo_rating_filter state property to PhotosState.ts (FR-006-04, S-006-08).
21+
- [x] T-006-02 – Add photo_rating_filter state property to PhotosState.ts (FR-006-04, S-006-08).
2222
_Intent:_ Add `photo_rating_filter: null | 1 | 2 | 3 | 4 | 5` property with default value `null`.
2323
_Verification commands:_
2424
- `npm run check` (TypeScript compilation)
2525
_Notes:_ Property should be reactive, type-safe.
2626

27-
- [ ] T-006-03 – Add photoRatingFilter getter to PhotosState.ts (FR-006-04).
27+
- [x] T-006-03 – Add photoRatingFilter getter to PhotosState.ts (FR-006-04).
2828
_Intent:_ Implement getter for accessing filter state.
2929
_Verification commands:_
3030
- `npm run check`
3131
_Notes:_ Use computed or simple getter pattern matching existing store patterns.
3232

33-
- [ ] T-006-04 – Add setPhotoRatingFilter action to PhotosState.ts (FR-006-04, S-006-03, S-006-06).
33+
- [x] T-006-04 – Add setPhotoRatingFilter action to PhotosState.ts (FR-006-04, S-006-03, S-006-06).
3434
_Intent:_ Implement action `setPhotoRatingFilter(rating: null | 1 | 2 | 3 | 4 | 5)` that updates filter state.
3535
_Verification commands:_
3636
- `npm run check`
3737
_Notes:_ Action should be type-safe, accept null to clear filter.
3838

39-
- [ ] T-006-05 – Write unit tests for PhotosState filter state (S-006-08, S-006-09).
39+
- [x] T-006-05 – Write unit tests for PhotosState filter state (S-006-08, S-006-09).
4040
_Intent:_ Test default value (null), setPhotoRatingFilter updates state correctly.
4141
_Verification commands:_
4242
- `npm run check` (includes unit tests)
@@ -46,32 +46,32 @@ _Last updated: 2026-01-03_
4646

4747
### Increment I2 – Filtering Logic Computed Property
4848

49-
- [ ] T-006-06 – Identify photo list rendering location (FR-006-02, FR-006-05).
49+
- [x] T-006-06 – Identify photo list rendering location (FR-006-02, FR-006-05).
5050
_Intent:_ Find where photo array is rendered (PhotoThumbPanel.vue or parent component).
5151
_Verification commands:_
5252
- File located and structure understood
5353
_Notes:_ May be in PhotoPanel.vue, PhotoThumbPanel.vue, or similar.
5454

55-
- [ ] T-006-07 – Add hasRatedPhotos computed property (FR-006-01, S-006-01, S-006-02).
55+
- [x] T-006-07 – Add hasRatedPhotos computed property (FR-006-01, S-006-01, S-006-02).
5656
_Intent:_ Create computed property that checks if any photo has user_rating > 0.
5757
_Verification commands:_
5858
- `npm run check`
5959
_Notes:_ `photos.value.some(p => p.user_rating && p.user_rating > 0)`.
6060

61-
- [ ] T-006-08 – Add filteredPhotos computed property (FR-006-02, FR-006-05, NFR-006-01, S-006-03, S-006-04, S-006-05).
61+
- [x] T-006-08 – Add filteredPhotos computed property (FR-006-02, FR-006-05, NFR-006-01, S-006-03, S-006-04, S-006-05).
6262
_Intent:_ Create computed property that filters photos by minimum rating threshold.
6363
_Verification commands:_
6464
- `npm run check`
6565
- `npm run dev` (manual testing with mock data)
6666
_Notes:_ Logic: if filter === null OR no rated photos → all photos; else → photos.filter(p => p.user_rating >= filter).
6767

68-
- [ ] T-006-09 – Update photo grid rendering to use filteredPhotos (FR-006-02, FR-006-05).
68+
- [x] T-006-09 – Update photo grid rendering to use filteredPhotos (FR-006-02, FR-006-05).
6969
_Intent:_ Change photo grid component to render filteredPhotos instead of photos array.
7070
_Verification commands:_
7171
- `npm run dev` (verify grid updates when filter changes)
7272
_Notes:_ May need to pass filteredPhotos as prop or use computed directly.
7373

74-
- [ ] T-006-10 – Write unit tests for filtering logic (S-006-03, S-006-04, S-006-05, S-006-07).
74+
- [x] T-006-10 – Write unit tests for filtering logic (S-006-03, S-006-04, S-006-05, S-006-07).
7575
_Intent:_ Test filter null → all photos, filter 3 → ≥3 stars, filter 5 → only 5 stars, no rated photos → all photos.
7676
_Verification commands:_
7777
- `npm run check`
@@ -81,32 +81,32 @@ _Last updated: 2026-01-03_
8181

8282
### Increment I3 – Star Filter Control Component Structure
8383

84-
- [ ] T-006-11 – Read PhotoThumbPanelControl.vue structure (FR-006-07).
84+
- [x] T-006-11 – Read PhotoThumbPanelControl.vue structure (FR-006-07).
8585
_Intent:_ Understand existing PhotoThumbPanelControl.vue layout and button structure.
8686
_Verification commands:_
8787
- File read and structure understood
8888
_Notes:_ Note location of layout buttons, spacing, styling patterns.
8989

90-
- [ ] T-006-12 – Import PhotosState store in PhotoThumbPanelControl.vue (FR-006-04).
90+
- [x] T-006-12 – Import PhotosState store in PhotoThumbPanelControl.vue (FR-006-04).
9191
_Intent:_ Import and setup PhotosState store to access filter state.
9292
_Verification commands:_
9393
- `npm run check`
9494
_Notes:_ Use `const photosStore = usePhotosStateStore()` or similar pattern.
9595

96-
- [ ] T-006-13 – Add hasRatedPhotos computed property to PhotoThumbPanelControl.vue (FR-006-01, S-006-01, S-006-02).
96+
- [x] T-006-13 – Add hasRatedPhotos computed property to PhotoThumbPanelControl.vue (FR-006-01, S-006-01, S-006-02).
9797
_Intent:_ Add computed property to detect if any photo has rating.
9898
_Verification commands:_
9999
- `npm run check`
100100
_Notes:_ May need to access photos array via props or store.
101101

102-
- [ ] T-006-14 – Add star filter template structure to PhotoThumbPanelControl.vue (FR-006-01, FR-006-07).
102+
- [x] T-006-14 – Add star filter template structure to PhotoThumbPanelControl.vue (FR-006-01, FR-006-07).
103103
_Intent:_ Add div with v-if="hasRatedPhotos", render 5 star buttons with v-for.
104104
_Verification commands:_
105105
- `npm run check`
106106
- `npm run dev` (visual inspection - stars appear when rated photos exist)
107107
_Notes:_ Position before layout buttons, use role="group" and aria-label.
108108

109-
- [ ] T-006-15 – Add ARIA attributes to star filter group (NFR-006-02).
109+
- [x] T-006-15 – Add ARIA attributes to star filter group (NFR-006-02).
110110
_Intent:_ Add role="group", aria-label="Filter by star rating" to star filter container.
111111
_Verification commands:_
112112
- `npm run check`
@@ -116,26 +116,26 @@ _Last updated: 2026-01-03_
116116

117117
### Increment I4 – Star Click Interaction (Toggle Behavior)
118118

119-
- [ ] T-006-16 – Implement handleStarClick method (FR-006-02, FR-006-03, S-006-03, S-006-06).
119+
- [x] T-006-16 – Implement handleStarClick method (FR-006-02, FR-006-03, S-006-03, S-006-06).
120120
_Intent:_ Add click handler that toggles filter (if current === clicked → clear, else → set).
121121
_Verification commands:_
122122
- `npm run check`
123123
- `npm run dev` (test click behavior)
124124
_Notes:_ Call photosStore.setPhotoRatingFilter(star) or (null).
125125

126-
- [ ] T-006-17 – Implement starIconClass method (FR-006-06).
126+
- [x] T-006-17 – Implement starIconClass method (FR-006-06).
127127
_Intent:_ Return filled or empty star icon class based on filter state.
128128
_Verification commands:_
129129
- `npm run dev` (visual inspection - correct stars filled)
130130
_Notes:_ If star <= filter → filled ('pi pi-star-fill'), else → empty ('pi pi-star').
131131

132-
- [ ] T-006-18 – Add star icon styling (FR-006-06).
132+
- [x] T-006-18 – Add star icon styling (FR-006-06).
133133
_Intent:_ Apply Tailwind classes for filled/empty stars (yellow vs gray).
134134
_Verification commands:_
135135
- `npm run dev` (visual inspection)
136136
_Notes:_ Filled: `text-yellow-500`, empty: `text-gray-300 dark:text-gray-600`.
137137

138-
- [ ] T-006-19 – Test star click toggle behavior manually (S-006-03, S-006-06, S-006-07).
138+
- [x] T-006-19 – Test star click toggle behavior manually (S-006-03, S-006-06, S-006-07).
139139
_Intent:_ Manually test: click star 3 → filter ≥3, click star 3 again → clear filter.
140140
_Verification commands:_
141141
- `npm run dev` (manual testing)
@@ -145,19 +145,19 @@ _Last updated: 2026-01-03_
145145

146146
### Increment I5 – Hover and Visual Feedback
147147

148-
- [ ] T-006-20 – Add hover styling to star buttons (FR-006-06, UI-006-04).
148+
- [x] T-006-20 – Add hover styling to star buttons (FR-006-06, UI-006-04).
149149
_Intent:_ Add hover effects: color preview, scale transform.
150150
_Verification commands:_
151151
- `npm run dev` (hover over stars, verify visual feedback)
152152
_Notes:_ Classes: `hover:text-yellow-400 hover:scale-110 transition-transform duration-150`.
153153

154-
- [ ] T-006-21 – Add focus styling for keyboard navigation (NFR-006-02).
154+
- [x] T-006-21 – Add focus styling for keyboard navigation (NFR-006-02).
155155
_Intent:_ Add visible focus outline for keyboard users.
156156
_Verification commands:_
157157
- `npm run dev` (tab to star filter, verify focus outline visible)
158158
_Notes:_ Classes: `focus:outline-none focus:ring-2 focus:ring-primary`.
159159

160-
- [ ] T-006-22 – Ensure touch targets are ≥44px on mobile (NFR-006-02).
160+
- [x] T-006-22 – Ensure touch targets are ≥44px on mobile (NFR-006-02).
161161
_Intent:_ Add padding to star buttons to meet minimum touch target size.
162162
_Verification commands:_
163163
- `npm run dev` (test in browser DevTools responsive mode)
@@ -167,20 +167,20 @@ _Last updated: 2026-01-03_
167167

168168
### Increment I6 – Keyboard Accessibility
169169

170-
- [ ] T-006-23 – Add aria-label and aria-pressed to each star button (NFR-006-02, UI-006-05).
170+
- [x] T-006-23 – Add aria-label and aria-pressed to each star button (NFR-006-02, UI-006-05).
171171
_Intent:_ Add accessibility attributes: aria-label="Filter by N stars or higher", aria-pressed based on active state.
172172
_Verification commands:_
173173
- `npm run check`
174174
- Manual screen reader testing (if available)
175175
_Notes:_ aria-pressed="true" when filter === star, else "false".
176176

177-
- [ ] T-006-24 – Implement keyboard event handlers (Arrow keys, Enter, Space) (NFR-006-02, UI-006-05).
177+
- [x] T-006-24 – Implement keyboard event handlers (Arrow keys, Enter, Space) (NFR-006-02, UI-006-05).
178178
_Intent:_ Add @keydown handler for arrow key navigation and Enter/Space activation.
179179
_Verification commands:_
180180
- Manual keyboard testing (Tab, Arrow Left/Right, Enter)
181181
_Notes:_ Arrow Right → focus next star, Arrow Left → focus prev star, Enter/Space → click.
182182

183-
- [ ] T-006-25 – Test keyboard navigation flow (NFR-006-02).
183+
- [x] T-006-25 – Test keyboard navigation flow (NFR-006-02).
184184
_Intent:_ Test full keyboard workflow: Tab to filter, Arrow keys to select star, Enter to activate, Tab out.
185185
_Verification commands:_
186186
- Manual keyboard testing
@@ -370,4 +370,4 @@ _Last updated: 2026-01-03_
370370

371371
---
372372

373-
_Last updated: 2026-01-03_
373+
_Last updated: 2026-01-14_

docs/specs/4-architecture/knowledge-map.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ This document tracks modules, dependencies, and architectural relationships acro
5353
#### Components
5454
- **UI Components** (`resources/js/components/`) - PrimeVue-based interface elements
5555
- Gallery components (album, photo, flow, search modules)
56+
- **PhotoThumbPanelControl** - Layout selector with star rating filter (Feature 006)
57+
- 5 clickable stars for minimum rating threshold filter
58+
- Conditional rendering (hidden when no rated photos)
59+
- Toggle behavior (click same star to clear)
60+
- Keyboard accessible (Arrow keys, Enter/Space)
5661
- Forms, modals, drawers, settings components
5762
- **Views** (`resources/js/views/`) - Page-level Vue components
5863
- Gallery views: Albums, Album, Favourites, Flow, Frame, Map, Search
@@ -65,6 +70,11 @@ This document tracks modules, dependencies, and architectural relationships acro
6570
#### State Management
6671
- **Pinia Stores** (`resources/js/stores/`) - Centralized state management
6772
- Auth, LycheeState, LeftMenuState, ModalsState, FlowState, FavouriteState
73+
- **PhotosState** - Photos collection management with rating filter support:
74+
- `photoRatingFilter` - Current filter setting (null | 1-5)
75+
- `hasRatedPhotos` getter - Checks if any photo has user rating
76+
- `filteredPhotos` getter - Returns photos filtered by minimum rating threshold
77+
- `filteredPhotosTimeline` getter - Returns timeline-grouped photos filtered by rating
6878
- Vue3 reactive state and composables
6979

7080
#### Routing
@@ -219,4 +229,4 @@ Replaces on-the-fly virtual column computation with physical database fields upd
219229

220230
---
221231

222-
*Last updated: January 10, 2026*
232+
*Last updated: January 14, 2026*

docs/specs/4-architecture/roadmap.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ High-level planning document for Lychee features and architectural initiatives.
66

77
| Feature ID | Name | Status | Priority | Assignee | Started | Updated |
88
|------------|------|--------|----------|----------|---------|---------|
9-
| 009 | Rating Ordering and Smart Albums | Planning | P2 | Agent | 2026-01-16 | 2026-01-16 |
10-
| 007 | Photos and Albums Pagination | In Progress | P1 | Agent | 2026-01-07 | 2026-01-08 |
119
| 004 | Album Size Statistics Pre-computation | Planning | P1 | - | 2026-01-02 | 2026-01-02 |
1210

1311
## Paused Features
@@ -20,6 +18,8 @@ High-level planning document for Lychee features and architectural initiatives.
2018

2119
| Feature ID | Name | Completed | Notes |
2220
|------------|------|-----------|-------|
21+
| 007 | Photos and Albums Pagination | 2026-01-14 | Client-side pagination for photos and albums, configurable page size, preserve state across navigation, optimized rendering performance |
22+
| 006 | Photo Star Rating Filter | 2026-01-14 | Frontend filter control (5 clickable stars) for minimum rating threshold, toggle on/off behavior, Pinia state persistence, keyboard accessible, filters photos in album view |
2323
| 005 | Album List View Toggle | 2026-01-04 | Toggle between grid/card and list view for albums, admin-configurable default, session-only user preference, full RTL support, drag-select compatible |
2424
| 003 | Album Computed Fields Pre-computation | 2026-01-02 | Event-driven pre-computation for 6 album fields (num_children, num_photos, min/max_taken_at, dual auto covers), AlbumBuilder virtual column removal, backfill/recovery commands, comprehensive test coverage |
2525
| 002 | Worker Mode Support | 2025-12-28 | Docker worker mode with queue processing, auto-restart, configurable QUEUE_NAMES/WORKER_MAX_TIME, multi-container deployment |
@@ -86,4 +86,4 @@ features/
8686

8787
---
8888

89-
*Last updated: 2026-01-16*
89+
*Last updated: 2026-01-21*

lang/ar/gallery.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@
6161
'grid' => 'مع النسبة، شبكة',
6262
'filmstrip' => 'شريط فيلم',
6363
],
64+
'filter' => [
65+
'by_rating' => 'Filter by star rating',
66+
'n_stars_or_higher' => 'Filter by :n stars or higher',
67+
],
6468
'overlay' => [
6569
'none' => 'لا شيء',
6670
'exif' => 'بيانات EXIF',

lang/cz/gallery.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@
6262
'grid' => 'With aspect, grid',
6363
'filmstrip' => 'Filmstrip',
6464
],
65+
'filter' => [
66+
'by_rating' => 'Filter by star rating',
67+
'n_stars_or_higher' => 'Filter by :n stars or higher',
68+
],
6569
'overlay' => [
6670
'none' => 'None',
6771
'exif' => 'EXIF data',

lang/de/gallery.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@
6161
'grid' => 'Mit Seitenverhältnis, Raster',
6262
'filmstrip' => 'Filmstreifen',
6363
],
64+
'filter' => [
65+
'by_rating' => 'Filter by star rating',
66+
'n_stars_or_higher' => 'Filter by :n stars or higher',
67+
],
6468
'overlay' => [
6569
'none' => 'Keine',
6670
'exif' => 'EXIF-Daten',

lang/el/gallery.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@
6262
'grid' => 'With aspect, grid',
6363
'filmstrip' => 'Filmstrip',
6464
],
65+
'filter' => [
66+
'by_rating' => 'Filter by star rating',
67+
'n_stars_or_higher' => 'Filter by :n stars or higher',
68+
],
6569
'overlay' => [
6670
'none' => 'None',
6771
'exif' => 'EXIF data',

lang/en/gallery.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@
6262
'grid' => 'With aspect, grid',
6363
'filmstrip' => 'Filmstrip',
6464
],
65+
'filter' => [
66+
'by_rating' => 'Filter by star rating',
67+
'n_stars_or_higher' => 'Filter by :n stars or higher',
68+
],
6569
'overlay' => [
6670
'none' => 'None',
6771
'exif' => 'EXIF data',

lang/es/gallery.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@
6262
'grid' => 'Con aspecto, cuadrícula',
6363
'filmstrip' => 'Tira de película',
6464
],
65+
'filter' => [
66+
'by_rating' => 'Filter by star rating',
67+
'n_stars_or_higher' => 'Filter by :n stars or higher',
68+
],
6569
'overlay' => [
6670
'none' => 'Ninguno',
6771
'exif' => 'Datos EXIF',

0 commit comments

Comments
 (0)