fix(rating): retain user-selected value (#24)#136
Conversation
frappe-ui Rating uses 1..N stars; Frappe stores Rating as a 0..1 fraction and clamps to [0, 1]. Without conversion, clicking N stars stored 1.0 and on reload only the first star rendered, losing the real selection. Wrap frappe-ui Rating in a component that converts 0..1 <-> 1..5 in both directions, and scale the value in the read-only submission view.
📝 WalkthroughWalkthroughIntroduces a custom Rating component wrapper that bridges Frappe's 0–1 fraction storage format with frappe-ui's 1–N integer star display format. Integrates the component into the field registry, updates submission display to apply the conversion, and validates the flow with an E2E test. ChangesRating field component and integration
Sequence DiagramsequenceDiagram
participant Storage as Frappe Storage
participant Component as Rating.vue
participant FrappeUI as FrappeRating
participant User as User
Storage->>Component: 0.6 (0..1 fraction)
Component->>FrappeUI: 3 stars (1..5 integer)
FrappeUI->>User: Display 3 stars
User->>FrappeUI: Click star
FrappeUI->>Component: New star value
Component->>Storage: 0.6 (0..1 fraction)
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add 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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
frontend/src/components/form/submissions/SubmissionFieldValue.vue (1)
103-108: ⚡ Quick winEliminate duplication by using the local Rating component.
The conversion logic
Math.round((Number(value) || 0) * 5)duplicates the same logic inRating.vue(line 20). This violates the DRY principle and creates a maintenance burden—if the conversion formula orMAX_STARSchanges, both locations must be updated.The local
Ratingcomponent already handles the 0..1 → stars conversion internally and supportsreadonlymode, so you can simplify this code by importing and using it directly.♻️ Proposed refactor to use the local Rating component
First, update the imports at the top of the file:
-import { Checkbox, Switch, Rating, TextEditor } from "frappe-ui"; +import { Checkbox, Switch, TextEditor } from "frappe-ui"; +import Rating from "`@/components/fields/Rating.vue`";Then replace the manual conversion with the local component:
<Rating v-else-if="fieldtype === Fieldtype.RATING" - :modelValue="Math.round((Number(value) || 0) * 5)" - :rating_from="5" + :modelValue="value" readonly />🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/form/submissions/SubmissionFieldValue.vue` around lines 103 - 108, Replace the duplicated conversion in SubmissionFieldValue.vue for Fieldtype.RATING by using the local Rating component’s built-in conversion: import/use the local Rating component (the one whose conversion logic is on line 20 in Rating.vue) and remove the manual Math.round((Number(value) || 0) * 5) expression; instead pass the raw value (or Number(value) if you prefer explicit typing) to :modelValue and keep readonly, so the local Rating component handles 0..1 → stars conversion centrally.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@frontend/src/components/form/submissions/SubmissionFieldValue.vue`:
- Around line 103-108: Replace the duplicated conversion in
SubmissionFieldValue.vue for Fieldtype.RATING by using the local Rating
component’s built-in conversion: import/use the local Rating component (the one
whose conversion logic is on line 20 in Rating.vue) and remove the manual
Math.round((Number(value) || 0) * 5) expression; instead pass the raw value (or
Number(value) if you prefer explicit typing) to :modelValue and keep readonly,
so the local Rating component handles 0..1 → stars conversion centrally.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2c474f46-d6b2-4791-9de4-fa54e3e4622f
📒 Files selected for processing (4)
frontend/e2e/specs/rating-field.spec.tsfrontend/src/components/fields/Rating.vuefrontend/src/components/form/submissions/SubmissionFieldValue.vuefrontend/src/config/fieldTypes.ts
Summary
Ratingworks in 1..N integer stars; Frappe stores Rating as a 0..1 fraction and clamps to[0, 1]. Without conversion, clicking N stars persisted 1.0 and on reload only the first star rendered, losing the real selection.Rating.vuewrapper converts 0..1 <-> 1..5 in both directions; readonly submission view scales the stored fraction to stars.Closes #24
Test plan
rating-field.spec.tsclicks the 3rd star on a published form and asserts the linked DocType stores 0.6 (red before fix, green after).yarn typecheckyarn lintform-submissionandsubmission-viewspecs still pass.Summary by CodeRabbit
Release Notes
New Features
Tests