Skip to content

Conversation

@Sartoric
Copy link
Contributor

@Sartoric Sartoric commented Dec 18, 2025

  • Implemented a toggle button to switch grid layout between horizontal and vertical orientations.

Summary by CodeRabbit

  • New Features
    • Added a header toggle to switch between up/down (compact vs expanded) dashboard layouts with an accessible label and dynamic icon.
    • Dashboard cards now reflow and adjust column spans based on the selected layout for improved organization and responsiveness.
    • Layout choice is persisted across visits so your preferred view is retained.
    • Header toggle is positioned in the top-right for easy access; existing dashboard controls and modes continue to work as before.

✏️ Tip: You can customize this high-level summary in your review settings.

- Implemented a toggle button to switch grid layout between horizontal and vertical orientations.
@cla-bot cla-bot bot added the cla-signed label Dec 18, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 18, 2025

Walkthrough

Adds 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

Cohort / File(s) Summary
Home Page — layout toggle & UI
web/src/pages/Home/index.jsx
Adds upDownLayout state initialized from getDashboardUpDownLayout, calls setDashboardUpDownLayout on change, imports FontAwesome icons, renders an accessible toggle button positioned in the header, replaces the static grid with a responsive gridUpDownClass, and conditionally adjusts Card column spans and ordering based on the toggle.
Dashboard manager — persistence helpers
web/src/utils/dashboardManager.js
Adds DASHBOARD_UPDOWN_LAYOUT_KEY, getDashboardUpDownLayout() and setDashboardUpDownLayout(layout) to read/write the upDownLayout boolean to localStorage with window/storage guards, input validation, and error logging.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify getDashboardUpDownLayout / setDashboardUpDownLayout handle absence of window/localStorage and log/errors as intended.
  • Confirm upDownLayout is correctly initialized and updates propagate to UI without excessive writes.
  • Check accessibility (ARIA/labels/keyboard) and positioning of the toggle on small viewports.
  • Validate responsive class switching (gridUpDownClass) and card span adjustments across breakpoints.

Poem

🐇
I nudged a little toggle bright,
Cards tumbled up then down by night.
Buried in a tiny key,
My layout sleeps in memory —
Hooray for tidy grids and light!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add layout toggle feature to Dashboard' directly and clearly describes the main change: implementing a toggle feature for dashboard layout switching between horizontal and vertical orientations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 dashboardLayout which persists via localStorage, the upDownLayout preference 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 dashboardLayout for cross-tab synchronization.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 21f08c1 and ac505e7.

📒 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.
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 that layout is 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 upDownLayout state (line 32) lacks a storage event listener, unlike dashboardLayout which 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

📥 Commits

Reviewing files that changed from the base of the PR and between ac505e7 and ee76cb0.

📒 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-label has 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.

@Sartoric Sartoric marked this pull request as draft December 18, 2025 12:38
- Introduced `DASHBOARD_UPDOWN_LAYOUT_KEY` constant for consistent key usage.
- Improved `setDashboardUpDownLayout` validation to ensure the layout is a boolean value.
@sonarqubecloud
Copy link

@Sartoric Sartoric marked this pull request as ready for review December 19, 2025 17:10
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between ee76cb0 and 4e7e310.

📒 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_KEY constant resolves the hardcoded localStorage key issue raised in the previous review. This improves maintainability and consistency with the existing DASHBOARD_LAYOUT_KEY pattern.


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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant