-
-
Notifications
You must be signed in to change notification settings - Fork 116
Add layout toggle feature to Dashboard #528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add layout toggle feature to Dashboard #528
Conversation
- Implemented a toggle button to switch grid layout between horizontal and vertical orientations.
WalkthroughAdds an up/down layout toggle to Home with persisted boolean state via new dashboardManager helpers and updates header UI and responsive grid classes to change card ordering and column spans based on the toggle. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/src/pages/Home/index.jsx (1)
27-28: Consider persisting the layout preference.Unlike
dashboardLayoutwhich persists via localStorage, theupDownLayoutpreference resets on each visit. Users may prefer their layout choice to be remembered.🔎 View suggested implementation
- const [upDownLayout, setUpDownLayout] = useState(false); + const [upDownLayout, setUpDownLayout] = useState(() => { + return localStorage.getItem('upDownLayout') === 'true'; + }); const gridUpDownClass = upDownLayout ? 'grid-cols-1' : 'grid-cols-10';Then update the toggle handler to persist:
onClick={() => { - setUpDownLayout(!upDownLayout); + const newLayout = !upDownLayout; + setUpDownLayout(newLayout); + localStorage.setItem('upDownLayout', newLayout); }}You may also want to add a storage event listener similar to
dashboardLayoutfor cross-tab synchronization.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
web/src/pages/Home/index.jsx(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: deploy
- GitHub Check: test
🔇 Additional comments (3)
web/src/pages/Home/index.jsx (3)
18-20: LGTM!The FontAwesome imports follow the recommended pattern for tree-shaking by importing individual icons rather than the entire icon library.
71-73: LGTM!The icon logic correctly represents the action that will be taken (switch to the opposite layout), which is a standard UX pattern for toggle buttons.
78-93: LGTM!The grid layout logic is correct:
- Horizontal layout: 10-column grid with 4+6 span distribution
- Vertical layout: Single-column grid with full-width cards
- Existing order controls are preserved
- Added `getDashboardUpDownLayout` and `setDashboardUpDownLayout` utility functions for localStorage sync. - Updated `Home` page to to persist changes and initialize layout state from localStorage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
web/src/utils/dashboardManager.js (1)
44-57: Validate or document the boolean parameter type.The setter accepts any non-null value but the getter expects a boolean stored as
'true'or'false'. While JavaScript's implicit type coercion handles this when a boolean is passed, the function should either validate thatlayoutis a boolean or document this requirement to prevent incorrect usage.🔎 Apply this diff to add type validation:
export const setDashboardUpDownLayout = layout => { - if (layout === null || layout === undefined) { - console.error('setDashboardUpDownLayout: Layout cannot be null or undefined'); + if (layout === null || layout === undefined || typeof layout !== 'boolean') { + console.error('setDashboardUpDownLayout: Layout must be a boolean value'); return false; }web/src/pages/Home/index.jsx (1)
35-49: Add storage event listener for cross-tab synchronization.The
upDownLayoutstate (line 32) lacks a storage event listener, unlikedashboardLayoutwhich listens for changes from other tabs (lines 38-42). This means if a user toggles the layout in one tab, other open tabs won't reflect the change.🔎 Apply this diff to add cross-tab sync:
useEffect(() => { setDashboardLayout(getDashboardLayout()); + setUpDownLayout(getDashboardUpDownLayout()); const handleStorageChange = e => { if (e.key === 'dashboardLayout') { setDashboardLayout(e.newValue || DASHBOARD_LAYOUTS.ORDER_FIRST); } + if (e.key === 'upDownLayout') { + setUpDownLayout(e.newValue === 'true'); + } }; window.addEventListener('storage', handleStorageChange); return () => { window.removeEventListener('storage', handleStorageChange); }; }, []);Also applies to: 32-32
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
web/src/pages/Home/index.jsx(2 hunks)web/src/utils/dashboardManager.js(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
web/src/pages/Home/index.jsx (1)
web/src/utils/dashboardManager.js (8)
setDashboardLayout(16-29)setDashboardLayout(16-29)DASHBOARD_LAYOUTS(59-62)DASHBOARD_LAYOUTS(59-62)getDashboardUpDownLayout(31-42)getDashboardUpDownLayout(31-42)setDashboardUpDownLayout(44-57)setDashboardUpDownLayout(44-57)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test
- GitHub Check: deploy
🔇 Additional comments (2)
web/src/pages/Home/index.jsx (2)
70-84: Great work addressing the accessibility issue!The
aria-labelhas been correctly added with dynamic text based on the layout state, making the toggle button accessible to screen readers.
86-101: Grid layout logic looks correct.The responsive grid implementation properly switches between single-column (vertical) and 10-column (horizontal) layouts, with card spans correctly distributing as 4 and 6 columns in horizontal mode.
- Introduced `DASHBOARD_UPDOWN_LAYOUT_KEY` constant for consistent key usage. - Improved `setDashboardUpDownLayout` validation to ensure the layout is a boolean value.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
web/src/utils/dashboardManager.js (1)
45-58: LGTM! Setter correctly validates and stores the boolean preference.The function properly validates the input as a boolean and stores it to localStorage. The implicit string conversion on line 52 works correctly with the getter's logic.
💡 Optional: Make string conversion explicit
For added clarity, you could explicitly convert the boolean to string:
try { - localStorage.setItem(DASHBOARD_UPDOWN_LAYOUT_KEY, layout); + localStorage.setItem(DASHBOARD_UPDOWN_LAYOUT_KEY, layout.toString()); return true;This is purely a readability improvement; the current implicit conversion works correctly.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
web/src/utils/dashboardManager.js(2 hunks)
🔇 Additional comments (2)
web/src/utils/dashboardManager.js (2)
2-2: Great fix! The constant definition addresses the previous review.The
DASHBOARD_UPDOWN_LAYOUT_KEYconstant resolves the hardcoded localStorage key issue raised in the previous review. This improves maintainability and consistency with the existingDASHBOARD_LAYOUT_KEYpattern.
32-43: LGTM! Clean implementation of the getter.The function correctly handles SSR scenarios, retrieves the boolean preference from localStorage, and includes appropriate error handling. The string comparison works as expected since localStorage stores all values as strings.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.