Skip to content
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

[WIP] Make the width of categories column in the budget view customizable #3445

Conversation

EvidentlyCube
Copy link

Background

It's the smallest deal breaker I ever had but after imported my nYNAB budgets I have a lot of categories which names don't fit in the available space on the budget view and in a lot of cases I can't shorten them and keep them meaningful enough for my needs:

image

What I've done

A new "Display" section in configuration - it supports values from 100 to 1024 (arbitrarily selected), gracefully handles incorrect input (resets to original value).
image

It should properly handle most UI elements (I've tried to find all the places that hardcoded the old width of 200 px):
image

Notes:

  • This is my first PR and I haven't even properly started using the application yet so there might be things I've missed
  • I wasn't exactly sure how to best handle not updating the pref with text values so used a temp variable and only actually update the setting on blur
  • I wasn't sure if local pref is the best place for this
  • I personally find this level of customization to lay somewhere between "basic" and "advanced" but I opted for the default settings because it seemed to fit neatly with theme and formatting

Finally, this does go a bit against the design strategy:

The goal of the UI is to be minimalistic [...] We are against adding a button/user setting for every little piece of UI (sizes, paddings, margins, etc.)

But at the same time the default 200 is awfully small, especially with upcoming i18n as many languages are much wider than English.

@actual-github-bot actual-github-bot bot changed the title Make the width of categories column in the budget view customizable [WIP] Make the width of categories column in the budget view customizable Sep 15, 2024
Copy link

netlify bot commented Sep 15, 2024

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit 7a5e6f6
🔍 Latest deploy log https://app.netlify.com/sites/actualbudget/deploys/66e73adce32129000812e6e5
😎 Deploy Preview https://deploy-preview-3445.demo.actualbudget.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

github-actions bot commented Sep 15, 2024

Bundle Stats — desktop-client

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
9 5.17 MB → 5.17 MB (+1.98 kB) +0.04%
Changeset
File Δ Size
src/components/settings/Display.tsx 🆕 +1.82 kB 0 B → 1.82 kB
src/components/settings/UI.tsx 📈 +539 B (+29.47%) 1.79 kB → 2.31 kB
src/components/budget/BudgetPageHeader.tsx 📈 +74 B (+10.69%) 692 B → 766 B
src/components/budget/DynamicBudgetTable.tsx 📈 +84 B (+2.85%) 2.88 kB → 2.96 kB
src/components/budget/rollover/budgetsummary/ToBudget.tsx 📈 +74 B (+2.72%) 2.65 kB → 2.73 kB
src/components/budget/BudgetTotals.tsx 📈 +84 B (+2.60%) 3.16 kB → 3.24 kB
src/components/budget/SidebarCategory.tsx 📈 +84 B (+1.66%) 4.95 kB → 5.03 kB
src/components/budget/SidebarGroup.tsx 📈 +84 B (+1.46%) 5.63 kB → 5.72 kB
src/components/budget/BudgetTable.jsx 📈 +74 B (+1.20%) 6.01 kB → 6.08 kB
src/components/settings/index.tsx 📈 +68 B (+1.09%) 6.1 kB → 6.17 kB
src/components/budget/rollover/RolloverComponents.tsx 📈 +84 B (+0.60%) 13.76 kB → 13.84 kB
src/components/settings/Format.tsx 📉 -547 B (-11.87%) 4.5 kB → 3.96 kB
src/components/settings/Themes.tsx 📉 -539 B (-23.04%) 2.28 kB → 1.76 kB
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
static/js/index.js 3.2 MB → 3.2 MB (+1.51 kB) +0.05%
static/js/wide.js 225.15 kB → 225.63 kB (+484 B) +0.21%

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
static/js/indexeddb-main-thread-worker-e59fee74.js 13.5 kB 0%
static/js/resize-observer.js 18.37 kB 0%
static/js/narrow.js 78.89 kB 0%
static/js/BackgroundImage.js 122.29 kB 0%
static/js/usePreviewTransactions.js 1.59 kB 0%
static/js/AppliedFilters.js 20.97 kB 0%
static/js/ReportRouter.js 1.5 MB 0%

Copy link
Contributor

github-actions bot commented Sep 15, 2024

Bundle Stats — loot-core

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
1 1.19 MB 0%

Changeset

No files were changed

View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

No assets were bigger

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.js 1.19 MB 0%

@EvidentlyCube
Copy link
Author

At the moment two VRT tests are failing.

settings.test.js:29:7 › Settings › checks the page visuals is expected as the settings has a new section in this PR

mobile.test.js:140:7 › Mobile › checks that settings page can be opened I think this one is also caused by a new section being added causing a slight shift in the text:

image

@youngcw
Copy link
Member

youngcw commented Sep 15, 2024

If the changes are expected then update the snapshots as part of the PR

@EvidentlyCube
Copy link
Author

@youngcw Thanks, I'll see what I can do! I am on Linux and so almost every VRT test fails due to a lot of tiny differences in font rendering, so I'll need to have some fun with getting development env up on my TV PC.

@youngcw
Copy link
Member

youngcw commented Sep 15, 2024

They get updated in docker for consistency. The package readme shows the process

@EvidentlyCube
Copy link
Author

They get updated in docker for consistency. The package readme shows the process

Ugh, I noticed docker and my brain immediately went "nah, I am good". Thanks, updated and checks are passing!

Things I am least confident about:

  1. 200 as the default value is hardcoded everywhere. It's no different from the number being hardcoded in the styles before but I am generally not too fond of it, especially that things depend on it being the same.
  2. I feel like there should be a way to force a default value for a local pref but I failed to find anything. It'd save the code from doing = 200 everywhere useLocalPref() happens.
  3. "Should this be in settings or somewhere else" is probably the biggest question. An ideal scenario would most likely be a way to drag the edge of the column and resize it with the mouse but that's not something I am willing to attempt unless I'll know it's something that would be accepted as a solution.

Otherwise I tried to mimic the code as best I could. It's the biggest React codebase I see and it's very intimidating to look at.

@jfdoming
Copy link
Contributor

They get updated in docker for consistency. The package readme shows the process

Ugh, I noticed docker and my brain immediately went "nah, I am good". Thanks, updated and checks are passing!

Things I am least confident about:

  1. 200 as the default value is hardcoded everywhere. It's no different from the number being hardcoded in the styles before but I am generally not too fond of it, especially that things depend on it being the same.
  2. I feel like there should be a way to force a default value for a local pref but I failed to find anything. It'd save the code from doing = 200 everywhere useLocalPref() happens.
  3. "Should this be in settings or somewhere else" is probably the biggest question. An ideal scenario would most likely be a way to drag the edge of the column and resize it with the mouse but that's not something I am willing to attempt unless I'll know it's something that would be accepted as a solution.

Otherwise I tried to mimic the code as best I could. It's the biggest React codebase I see and it's very intimidating to look at.

I do think there's #3309 which might attempt mouse resize as well

@EvidentlyCube
Copy link
Author

I do think there's #3309 which might attempt mouse resize as well

It does mouse resize indeed. Then there's a reason to get back to this PR once the other one is merged and rewrite it to use mouse instead.

@Jonathan-Fang
Copy link
Contributor

Rewrite using the mouse to drag the edge or the column sounds like a great idea! It can help fill the whitespace on 1920x1080 monitors too.

Copy link
Contributor

👋 Hi! It looks like this PR has not had any changes for a week now. Would you like someone to review this PR? If so - please remove the "[WIP]" prefix from the PR title. That will let the community know that this PR is open for a review.

@github-actions github-actions bot added the Stale label Sep 26, 2024
Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

Walkthrough

The changes introduce a new hook, useLocalPref, across various components in the budget management section of the application. This hook retrieves user-defined preferences for the width of budget categories, replacing hardcoded values with dynamically adjustable widths. Additionally, a new DisplaySettings component is introduced to manage these preferences interactively, allowing users to set and validate their preferred widths.

Changes

File Change Summary
packages/desktop-client/src/components/budget/BudgetPageHeader.tsx, BudgetTable.jsx, BudgetTotals.tsx, DynamicBudgetTable.tsx, SidebarCategory.tsx, SidebarGroup.tsx, rollover/RolloverComponents.tsx, rollover/budgetsummary/ToBudget.tsx Introduced useLocalPref hook to manage categoryWidth, replacing hardcoded values with user-defined preferences.
packages/desktop-client/src/components/settings/Display.tsx Added a new DisplaySettings component for managing and validating category width input.
packages/desktop-client/src/components/settings/Format.tsx, Themes.tsx Removed locally defined Column component and imported it from the UI module.
packages/desktop-client/src/components/settings/UI.tsx Introduced a new Column component for reusable layout.
packages/loot-core/src/types/prefs.d.ts Added a new property 'category.width' to the LocalPrefs type.

Possibly related PRs

Suggested labels

#sparkles: Merged


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 3

🧹 Outside diff range and nitpick comments (24)
packages/desktop-client/src/components/budget/BudgetPageHeader.tsx (2)

19-20: LGTM: Usage of useLocalPref hook for category width.

The useLocalPref hook is correctly used to retrieve the customizable category width. The default value of 200 ensures backward compatibility with the previous implementation.

Consider adding a comment explaining the purpose of this preference for better code readability:

+  // Retrieve the user-defined category width or use the default of 200 pixels
   const [categoryWidth = 200] = useLocalPref('category.width');

22-22: LGTM: Application of categoryWidth in component styling.

The categoryWidth is correctly applied to set the marginLeft style property, implementing the customizable width feature as intended.

To improve code readability, consider extracting the margin calculation to a constant:

+  const categoryMargin = 5;
+  const totalMarginLeft = categoryWidth + categoryMargin;
-  <View style={{ marginLeft: categoryWidth + 5, flexShrink: 0 }}>
+  <View style={{ marginLeft: totalMarginLeft, flexShrink: 0 }}>

This change would make the purpose of the additional 5 pixels more explicit and easier to maintain.

packages/desktop-client/src/components/settings/Themes.tsx (1)

18-18: Approved: Good move towards modularity.

The change to import Column from './UI' instead of defining it locally is a positive step towards better code organization and reusability. This aligns well with the DRY (Don't Repeat Yourself) principle and makes the codebase more maintainable.

Consider grouping related imports together. You could move this import statement next to other UI-related imports for better readability:

import { Select } from '../common/Select';
import { Text } from '../common/Text';
import { View } from '../common/View';
+import { Column, Setting } from './UI';
import { useSidebar } from '../sidebar/SidebarProvider';

-import { Column, Setting } from './UI';
packages/loot-core/src/types/prefs.d.ts (2)

70-70: LGTM! Consider adding a comment for clarity.

The addition of the 'category.width' property to the LocalPrefs type is well-placed and correctly typed. It aligns with the PR objective of making the category width customizable.

Consider adding a brief comment to explain the purpose and expected range of this property, similar to other properties in this type. For example:

/** Width of the category column in pixels (range: 100-1024) */
'category.width': number;

This would improve code readability and provide context for other developers.


Line range hint 1-94: Overall, the change is well-implemented and aligns with the PR objectives.

The addition of the 'category.width' property to the LocalPrefs type is a good foundation for implementing customizable category widths in the budget view. This change:

  1. Maintains type safety by explicitly defining the new preference.
  2. Keeps the property optional, ensuring backward compatibility.
  3. Correctly places the preference in the LocalPrefs type, as it's a device-specific setting.

As the project evolves, consider the following suggestions for future improvements:

  1. If more UI customization options are added in the future, it might be beneficial to group them under a nested 'ui' object within LocalPrefs, similar to the existing 'ui.showClosedAccounts'.
  2. Consider adding runtime validation for the 'category.width' value to ensure it stays within the intended range (100-1024 pixels). This could be implemented in the logic that reads/writes this preference.
  3. As mentioned in the PR comments, a more user-friendly approach in the long term might be to implement draggable column resizing. When that feature is implemented, this preference could serve as the initial or default width.
packages/desktop-client/src/components/settings/UI.tsx (1)

12-31: LGTM: Well-structured Column component with a minor suggestion.

The new Column component is well-implemented, using appropriate common UI elements and following good practices for layout and reusability.

Consider extracting the inline styles into separate style objects for better readability and maintainability. For example:

const columnStyle = {
  alignItems: 'flex-start',
  flexGrow: 1,
  gap: '0.5em',
  width: '100%',
};

const childrenContainerStyle = {
  alignItems: 'flex-start',
  gap: '1em',
};

export function Column({ title, children }: ColumProps) {
  return (
    <View style={columnStyle}>
      <Text style={{ fontWeight: 500 }}>{title}</Text>
      <View style={childrenContainerStyle}>{children}</View>
    </View>
  );
}

This approach can make the component more readable and easier to maintain in the future.

packages/desktop-client/src/components/budget/rollover/budgetsummary/ToBudget.tsx (2)

33-33: LGTM: Dynamic width adjustment implemented

The implementation of useLocalPref for category.width and its application to the Popover component's style successfully addresses the PR objective of making the categories column width customizable. This change allows for better flexibility in accommodating different category name lengths and internationalization requirements.

Consider extracting the default value (200) to a named constant at the top of the file for better maintainability. For example:

const DEFAULT_CATEGORY_WIDTH = 200;

// ...

const [categoryWidth = DEFAULT_CATEGORY_WIDTH] = useLocalPref('category.width');

This would make it easier to update the default width in the future if needed.

Also applies to: 65-65


Add Unit Tests for ToBudget Component

While an end-to-end test exists for the ToBudget component, there are no unit tests covering its new customizable width feature. To ensure comprehensive test coverage and maintain component reliability, please add unit tests that specifically target the ToBudget component's functionality.

🔗 Analysis chain

Line range hint 1-114: Consider updating related tests

The changes to the ToBudget component, while minimal, introduce new behavior that may affect existing tests.

To ensure the changes are properly covered by tests, please run the following command to check for any tests related to this component:

If any test files are found, please review and update them to account for the new dynamic width behavior. If no tests are found, consider adding new tests to cover this functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for test files related to ToBudget component
rg -t js -t jsx -t ts -t tsx --glob '**/*.test.*' 'ToBudget'

Length of output: 88


Script:

#!/bin/bash
# Search for test files related to ToBudget component
rg --glob '**/*.test.{js,jsx,ts,tsx}' 'ToBudget'

Length of output: 149

packages/desktop-client/src/components/budget/BudgetTotals.tsx (2)

29-29: LGTM: useLocalPref hook is correctly implemented.

The usage of useLocalPref to retrieve the categoryWidth is appropriate and maintains backward compatibility with the default value of 200.

Consider adding a comment explaining the purpose of this preference for better code readability:

// Retrieve user-defined category width or use default of 200 pixels
const [categoryWidth = 200] = useLocalPref('category.width');

Line range hint 1-114: Summary: Implementation successfully addresses PR objectives

The changes in this file effectively implement the customizable category width feature as outlined in the PR objectives. The use of the useLocalPref hook allows for user-defined preferences while maintaining backward compatibility with the default width of 200 pixels.

A few points to consider:

  1. The implementation is clean and consistent with React best practices.
  2. The changes align well with the goal of addressing the issue of category names not fitting within a fixed width.
  3. This implementation provides a good foundation for potential future enhancements, such as the draggable column edge mentioned in the PR comments.

As the PR author mentioned concerns about hardcoding the default width throughout the codebase, consider creating a constant for the default width in a central configuration file. This would make it easier to update the default value across the entire application if needed in the future.

Example:

// In a config file (e.g., src/config/uiDefaults.ts)
export const DEFAULT_CATEGORY_WIDTH = 200;

// In BudgetTotals.tsx
import { DEFAULT_CATEGORY_WIDTH } from '../../config/uiDefaults';

// ...

const [categoryWidth = DEFAULT_CATEGORY_WIDTH] = useLocalPref('category.width');

This approach would address the concern about dependencies and make the codebase more maintainable.

packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx (2)

16-16: LGTM: Simplified estimatedTableWidth calculation.

The removal of the fixed subtraction aligns with the goal of making the category width customizable. However, consider updating the getNumPossibleMonths function to account for the variable category width explicitly.

You might want to update the function signature and implementation to include the categoryWidth as a parameter:

function getNumPossibleMonths(width: number, categoryWidth: number) {
  const estimatedTableWidth = width - categoryWidth;
  // Rest of the function remains the same
}

This change would make the function more flexible and accurately reflect the customizable nature of the category width.


50-53: LGTM: Introduction of useLocalPref and updated calculations.

The changes successfully implement the customizable category width feature:

  1. The useLocalPref hook retrieves the user-defined category width.
  2. The numPossible calculation now accounts for the variable category width.
  3. The maxWidth calculation uses the dynamic categoryWidth.

These modifications align well with the PR objective.

For improved clarity, consider adding a brief comment explaining the significance of the categoryWidth preference:

// Retrieve user-defined category width (in pixels) from local preferences
const [categoryWidth = 200] = useLocalPref('category.width');
packages/desktop-client/src/components/settings/Format.tsx (1)

Line range hint 1-138: LGTM! Consider further UI component abstraction.

The removal of the local Column component and its import from a centralized UI module is a positive change that improves code organization and maintainability. This refactoring aligns well with the project's goals and best practices.

For future improvements, consider abstracting other UI components used in this file (such as Select, Checkbox, and Text) into the centralized UI module if they are used across multiple components. This would further enhance consistency and reusability throughout the application.

packages/desktop-client/src/components/budget/SidebarCategory.tsx (3)

51-51: LGTM: useLocalPref hook is correctly implemented.

The usage of useLocalPref to retrieve the category width is correct and follows React hooks conventions. The default value of 200 aligns with the previously hardcoded value.

Consider adding a comment explaining the significance of the 'category.width' key and the default value of 200 for better code documentation:

// Retrieve the user-defined category width or use the default of 200 pixels
const [categoryWidth = 200] = useLocalPref('category.width');

97-97: LGTM: categoryWidth is correctly applied to component styles.

The categoryWidth value is properly used to set the width of both the Popover and the main View component, successfully implementing the customizable width feature.

Consider adding a minimum width constraint to ensure the component remains usable even with very small width values:

<View
  style={{
    width: categoryWidth,
    minWidth: 100, // Ensure a minimum usable width
    // ... other styles
  }}
>

This change would align with the PR objective of allowing widths between 100 and 1024 pixels while preventing potential layout issues with extremely small widths.

Also applies to: 136-136


Hardcoded width values still present in multiple files

The verification revealed that there are remaining hardcoded width values of 200 in the following files:

  • packages/desktop-client/src/components/table.tsx
  • packages/desktop-client/src/components/filters/SavedFilterMenuButton.tsx
  • packages/desktop-client/src/components/budget/IncomeHeader.tsx

These instances should be updated to utilize the categoryWidth preference to ensure consistency and flexibility across the application.

🔗 Analysis chain

Line range hint 1-193: Overall assessment: Changes successfully implement customizable category width.

The modifications to SidebarCategory.tsx effectively implement the feature for customizable category widths, aligning well with the PR objectives. The changes:

  1. Introduce the useLocalPref hook to retrieve user preferences.
  2. Replace hardcoded width values with the dynamic categoryWidth.
  3. Apply the custom width to relevant components consistently.

These changes address the issue of category names not fitting within a fixed width and provide users with the ability to customize the categories column width.

While the current implementation is sound, consider the following for future improvements:

  1. Implement a draggable column edge for resizing, as mentioned in the PR comments. This would provide a more intuitive user experience.
  2. Explore the possibility of using CSS variables for the width, which could simplify updates across multiple components and stylesheets.

To ensure that the changes don't introduce any regressions, please run the following verification script:

This script will help identify any inconsistencies in the implementation of the customizable width feature across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the categoryWidth is consistently applied and that no hardcoded values remain

# Test 1: Check for any remaining hardcoded width values of 200
echo "Checking for hardcoded width values:"
rg --type typescript --type javascript "width:?\s*200" packages/desktop-client/src

# Test 2: Verify consistent usage of categoryWidth
echo "Verifying consistent usage of categoryWidth:"
rg --type typescript --type javascript "categoryWidth" packages/desktop-client/src

# Test 3: Check for proper import and usage of useLocalPref
echo "Checking for proper import and usage of useLocalPref:"
rg --type typescript --type javascript "useLocalPref.*category\.width" packages/desktop-client/src

Length of output: 672


Script:

#!/bin/bash
# Description: Verify that the categoryWidth is consistently applied and that no hardcoded values remain

# Test 1: Check for any remaining hardcoded width values of 200
echo "Checking for hardcoded width values:"
rg --type tsx --type ts "width:?\s*200" packages/desktop-client/src

# Test 2: Verify consistent usage of categoryWidth
echo "Verifying consistent usage of categoryWidth:"
rg --type tsx --type ts "categoryWidth" packages/desktop-client/src

# Test 3: Check for proper import and usage of useLocalPref
echo "Checking for proper import and usage of useLocalPref:"
rg --type tsx --type ts "useLocalPref.*category\.width" packages/desktop-client/src

Length of output: 606


Script:

#!/bin/bash
# Description: Verify that the categoryWidth is consistently applied and that no hardcoded values remain

# Test 1: Check for any remaining hardcoded width values of 200
echo "Checking for hardcoded width values:"
rg "width:?\s*200" packages/desktop-client/src --glob "*.ts" --glob "*.tsx"

# Test 2: Verify consistent usage of categoryWidth
echo "Verifying consistent usage of categoryWidth:"
rg "categoryWidth" packages/desktop-client/src --glob "*.ts" --glob "*.tsx"

# Test 3: Check for proper import and usage of useLocalPref
echo "Checking for proper import and usage of useLocalPref:"
rg "useLocalPref.*category\.width" packages/desktop-client/src --glob "*.ts" --glob "*.tsx"

Length of output: 4188

packages/desktop-client/src/components/budget/SidebarGroup.tsx (3)

56-56: LGTM: useLocalPref hook is correctly implemented.

The useLocalPref hook is properly used to retrieve the category width preference with a default value of 200 pixels. This aligns with the PR objectives.

Consider adding a comment explaining the significance of the 200px default value for better code readability:

// Default category width is 200px if no user preference is set
const [categoryWidth = 200] = useLocalPref('category.width');

114-114: LGTM: categoryWidth is correctly applied to component styles.

The categoryWidth variable is properly used to replace hardcoded values in both the Popover and View components' style props. This change allows for dynamic sizing based on user preferences, which aligns with the PR objectives.

For consistency and to avoid potential bugs in the future, consider using a constant for the default width. This could be defined at the top of the file or in a separate constants file:

const DEFAULT_CATEGORY_WIDTH = 200;

// Then use it like this:
const [categoryWidth = DEFAULT_CATEGORY_WIDTH] = useLocalPref('category.width');

This approach would ensure that the default width is consistent throughout the component and make it easier to update in the future if needed.

Also applies to: 159-159


Found remaining hardcoded width values in multiple files.

The verification scripts have identified several instances where categoryWidth is still hardcoded to 200 within the following files:

  • SidebarGroup.tsx:56
  • SidebarCategory.tsx:51
  • BudgetTotals.tsx:29
  • BudgetPageHeader.tsx:19
  • DynamicBudgetTable.tsx:50
  • RolloverComponents.tsx:196
  • ToBudget.tsx:33
  • IncomeHeader.tsx:22

These hardcoded values override the customizable widths intended by the recent changes. To ensure full adherence to the PR objectives:

  • Remove or refactor the default assignments of categoryWidth to allow full customization.
  • Verify that all components dynamically use the categoryWidth without default fallbacks.

Addressing these points will help maintain consistency and flexibility in category width management across the codebase.

🔗 Analysis chain

Line range hint 1-210: Overall assessment: Changes successfully implement customizable category widths.

The modifications to SidebarGroup.tsx effectively introduce the ability to customize category widths as per the PR objectives. The implementation is clean, follows React best practices, and integrates well with the existing code structure. The use of the useLocalPref hook ensures that user preferences are respected while maintaining a sensible default.

A few minor suggestions have been made to improve code clarity and consistency, but these are not critical issues. The changes appear to be ready for integration, pending any additional tests or verifications that may be required as part of the broader pull request.

To ensure that these changes don't introduce any unintended side effects, please run the following verification script:

This script will help identify any remaining hardcoded width values, ensure consistent usage of categoryWidth, and check for potential layout issues that might be affected by the dynamic width.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the categoryWidth is used consistently and that there are no remaining hardcoded width values.

# Test 1: Check for any remaining hardcoded width values of 200
echo "Checking for remaining hardcoded width values:"
rg --type typescript -n '(width|Width).*200' packages/desktop-client/src/components/budget/

# Test 2: Verify consistent usage of categoryWidth
echo "Verifying consistent usage of categoryWidth:"
rg --type typescript -n 'categoryWidth' packages/desktop-client/src/components/budget/

# Test 3: Check for any potential layout issues caused by the dynamic width
echo "Checking for potential layout issues:"
rg --type typescript -n '(flex|flexGrow|flexShrink|flexBasis)' packages/desktop-client/src/components/budget/

Length of output: 684


Script:

#!/bin/bash
# Description: Verify that the categoryWidth is used consistently and that there are no remaining hardcoded width values.

# Test 1: Check for any remaining hardcoded width values of 200
echo "Checking for remaining hardcoded width values:"
rg --type ts -n '(width|Width).*200' packages/desktop-client/src/components/budget/

# Test 2: Verify consistent usage of categoryWidth
echo "Verifying consistent usage of categoryWidth:"
rg --type ts -n 'categoryWidth' packages/desktop-client/src/components/budget/

# Test 3: Check for any potential layout issues caused by the dynamic width
echo "Checking for potential layout issues:"
rg --type ts -n '(flex|flexGrow|flexShrink|flexBasis)' packages/desktop-client/src/components/budget/

Length of output: 13154

packages/desktop-client/src/components/settings/index.tsx (1)

28-28: Summary: Changes align with PR objectives and maintain code integrity.

The changes in this file are minimal and focused, successfully introducing the new DisplaySettings feature as per the PR objectives. The import statement and component placement are appropriate and non-disruptive to the existing code structure. These modifications lay the groundwork for implementing customizable category width settings in the budget view.

However, to ensure full functionality:

  1. Verify that the DisplaySettings component in Display.tsx is fully implemented with the necessary logic for managing category width preferences.
  2. Confirm that the useLocalPref hook is correctly utilized within the DisplaySettings component to handle user preferences.
  3. Ensure that the new settings are properly applied in the budget view components where category widths are rendered.

Consider the following architectural points:

  1. Evaluate whether the DisplaySettings component should include any default values or constraints for the category width setting.
  2. Assess the need for any migration logic to handle existing users' preferences when introducing this new setting.
  3. Plan for potential future expansions of display settings to ensure the current implementation is scalable.

Also applies to: 179-179

packages/desktop-client/src/components/budget/BudgetTable.jsx (3)

37-37: LGTM: New state variable for category width.

The categoryWidth state variable is correctly implemented using the useLocalPref hook, allowing for persistent storage of the user's preference. The default value of 200 ensures backward compatibility with the previous implementation.

Consider adding a comment to explain the significance of the default value:

const [categoryWidth = 200] = useLocalPref('category.width'); // Default width: 200px

187-187: LGTM: Dynamic width applied to category View component.

The categoryWidth state variable is correctly used to set the width of the category View component, replacing the hardcoded value. This change successfully implements the customizable width feature.

Consider adding an aria-label or data-testid attribute to this View component to improve accessibility and testability:

<View style={{ width: categoryWidth }} aria-label="category-column" />

Multiple hardcoded widths of 200 found in the codebase.

The verification identified several instances where width: 200 is hardcoded in various components:

  • LoadBackupModal.jsx
  • ImportTransactionsModal.jsx
  • TransactionList.jsx
  • SelectLinkedAccountsModal.jsx

Please review these instances to determine if they should be updated to use the useLocalPref('category.width') hook or if they serve a different purpose.

🔗 Analysis chain

Line range hint 1-248: Overall implementation looks good, but verify impact on other components.

The changes to implement the customizable category width feature are minimal, focused, and well-implemented. The use of useLocalPref for persistent storage and the maintenance of backward compatibility with the default value are commendable.

To ensure the changes don't negatively impact other parts of the application, please run the following verification script:


Please run the following corrected verification script to ensure all hardcoded category widths and uses of the 'category.width' preference are properly checked:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for hardcoded category widths that might need updating

# Test: Search for hardcoded category widths
echo "Searching for hardcoded category widths..."
rg --type js --type jsx -i '(width|flex).*200' packages/desktop-client/src

# Test: Search for other uses of the 'category.width' preference
echo "Searching for other uses of the 'category.width' preference..."
rg --type js --type jsx -i "useLocalPref.*'category.width'" packages/desktop-client/src

echo "Please review the results to ensure all relevant components are updated."

Length of output: 619


Script:

# 
#!/bin/bash
# Description: Check for hardcoded category widths that might need updating

# Define 'jsx' file type for ripgrep
rg --type-add 'jsx:*.jsx' --type js --type jsx -i '(width|flex).*200' packages/desktop-client/src

# Search for other uses of the 'category.width' preference
rg --type-add 'jsx:*.jsx' --type js --type jsx -i "useLocalPref.*'category.width'" packages/desktop-client/src

echo "Please review the results to ensure all relevant components are updated."

Length of output: 1459

packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx (1)

196-196: LGTM: Correct usage of useLocalPref hook.

The useLocalPref hook is used correctly to retrieve the 'category.width' preference with a default value of 200. This aligns with the PR objectives of making the category width customizable.

Consider adding a brief comment explaining the purpose of this preference for better code readability:

// Retrieve user-defined category width or use default of 200 pixels
const [categoryWidth = 200] = useLocalPref('category.width');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c5193b6 and 7a5e6f6.

🔇 Files ignored due to path filters (7)
  • packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-4-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-5-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-checks-that-settings-page-can-be-opened-6-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/settings.test.js-snapshots/Settings-checks-the-page-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/settings.test.js-snapshots/Settings-checks-the-page-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/settings.test.js-snapshots/Settings-checks-the-page-visuals-3-chromium-linux.png is excluded by !**/*.png
  • upcoming-release-notes/3445.md is excluded by !**/*.md
📒 Files selected for processing (14)
  • packages/desktop-client/src/components/budget/BudgetPageHeader.tsx (2 hunks)
  • packages/desktop-client/src/components/budget/BudgetTable.jsx (2 hunks)
  • packages/desktop-client/src/components/budget/BudgetTotals.tsx (4 hunks)
  • packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx (2 hunks)
  • packages/desktop-client/src/components/budget/SidebarCategory.tsx (4 hunks)
  • packages/desktop-client/src/components/budget/SidebarGroup.tsx (4 hunks)
  • packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx (4 hunks)
  • packages/desktop-client/src/components/budget/rollover/budgetsummary/ToBudget.tsx (3 hunks)
  • packages/desktop-client/src/components/settings/Display.tsx (1 hunks)
  • packages/desktop-client/src/components/settings/Format.tsx (1 hunks)
  • packages/desktop-client/src/components/settings/Themes.tsx (1 hunks)
  • packages/desktop-client/src/components/settings/UI.tsx (1 hunks)
  • packages/desktop-client/src/components/settings/index.tsx (2 hunks)
  • packages/loot-core/src/types/prefs.d.ts (1 hunks)
🔇 Additional comments not posted (20)
packages/desktop-client/src/components/budget/BudgetPageHeader.tsx (2)

4-4: LGTM: Import statement for useLocalPref hook.

The import statement for the useLocalPref hook is correctly added and follows the project's import conventions.


Line range hint 1-38: Overall implementation of customizable category width looks good.

The changes in this file successfully implement the customizable category width feature as described in the PR objectives. The use of the useLocalPref hook is an appropriate approach for managing user preferences, and the implementation maintains backward compatibility with the default value.

The changes are minimal and well-integrated into the existing component structure. They effectively address the issue of fixed category widths while allowing for user customization.

To ensure that this change doesn't introduce any unintended side effects, please run the following verification script:

This script will help identify any remaining hardcoded category widths and ensure consistent use of the useLocalPref hook for the category width setting.

✅ Verification successful

<!-- [monologue]
[task final_response_1/1]
Conclude the verification process based on the shell script results.
[observations]
- The shell script successfully identified all instances where `useLocalPref('category.width')` is used with a default value of `200`.
- No hardcoded category widths outside the use of `useLocalPref` were found.
- The use of the `useLocalPref` hook is consistent across the codebase.
[analysis]
- The absence of hardcoded category widths ensures that the new dynamic width feature is implemented correctly.
- Consistent use of the `useLocalPref` hook indicates that user preferences are managed uniformly.
- The default value of `200` maintains backward compatibility without introducing fixed widths.
[actions]
- Since the verification confirms that there are no unintended hardcoded category widths and that `useLocalPref` is used consistently, the verification process can be concluded successfully.
-->

✅ Verification Successful

All category width settings are managed using the useLocalPref hook with a default value of 200. No hardcoded category widths were found outside of this implementation, and the hook is used consistently across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any hardcoded category widths that might conflict with the new dynamic width

# Test: Search for hardcoded category widths
echo "Checking for hardcoded category widths:"
rg --type typescript --type javascript "(?i)(category.*width|width.*category).*200" ./packages/desktop-client/src

# Test: Verify that the useLocalPref hook is used consistently
echo "Checking for consistent use of useLocalPref hook:"
rg --type typescript --type javascript "useLocalPref\(['\"]category\.width['\"]\)" ./packages/desktop-client/src

Length of output: 502


Script:

#!/bin/bash
# Description: Re-check for any hardcoded category widths and verify consistent use of useLocalPref hook using file extensions

# Test: Search for hardcoded category widths
echo "Checking for hardcoded category widths:"
rg "(?i)(category.*width|width.*category).*200" ./packages/desktop-client/src -g "*.ts" -g "*.tsx" -A 2

# Test: Verify that the useLocalPref hook is used consistently
echo "Checking for consistent use of useLocalPref hook:"
rg "useLocalPref\(['\"]category\.width['\"]\)" ./packages/desktop-client/src -g "*.ts" -g "*.tsx" -A 2

Length of output: 5886

packages/desktop-client/src/components/settings/Display.tsx (2)

1-14: LGTM: Imports and hooks are well-structured.

The imports and hooks are appropriately chosen for the component's functionality. The use of useLocalPref for managing the category width preference is a good approach for persisting user settings.


1-68: Overall functionality meets requirements, with room for minor improvements.

The DisplaySettings component successfully implements the customizable categories column width as described in the PR objectives. Good job on using local preferences for persistence and implementing input validation.

Suggestions for improvement:

  1. Add visual feedback for invalid inputs (e.g., a warning message or color change).
  2. Consider adding a reset button to revert to the default width.
  3. Implement debounce on the input to reduce unnecessary updates.

To ensure the component is properly integrated, run the following script:

This script will help verify that the DisplaySettings component is properly integrated into the main settings and that the useLocalPref hook is used correctly for the category width.

✅ Verification successful

DisplaySettings component is properly integrated and functions as expected.

The DisplaySettings component is correctly imported and utilized within the main settings component. Additionally, the useLocalPref hook with 'category.width' is appropriately implemented across relevant components, ensuring consistent behavior.

No issues were found during the verification process.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of DisplaySettings component

# Test: Check if DisplaySettings is imported and used in the main settings component
rg --type typescript 'import.*DisplaySettings' packages/desktop-client/src/components/settings
rg --type typescript '<DisplaySettings' packages/desktop-client/src/components/settings

# Test: Verify the usage of useLocalPref hook with 'category.width'
rg --type typescript "useLocalPref\\('category\\.width'" packages/desktop-client/src

Length of output: 382


Script:

#!/bin/bash
# Description: Verify the integration of DisplaySettings component

# Test: Check if DisplaySettings is imported and used in the main settings component
rg --type tsx 'import.*DisplaySettings' packages/desktop-client/src/components/settings
rg --type tsx '<DisplaySettings' packages/desktop-client/src/components/settings

# Test: Verify the usage of useLocalPref hook with 'category.width'
rg --type tsx "useLocalPref\\('category\\.width'" packages/desktop-client/src

Length of output: 340


Script:

#!/bin/bash
# Description: Verify the integration of DisplaySettings component

# Test: Check if DisplaySettings is imported and used in the main settings component
rg --type typescriptreact 'import.*DisplaySettings' packages/desktop-client/src/components/settings
rg --type typescriptreact '<DisplaySettings' packages/desktop-client/src/components/settings

# Test: Verify the usage of useLocalPref hook with 'category.width'
rg --type typescriptreact "useLocalPref\\('category\\.width'" packages/desktop-client/src

Length of output: 412


Script:

#!/bin/bash
# Description: Verify the integration of DisplaySettings component without using --type flag

# Test: Check if DisplaySettings is imported and used in the main settings component
rg 'import.*DisplaySettings' packages/desktop-client/src/components/settings --glob '*.tsx'
rg '<DisplaySettings' packages/desktop-client/src/components/settings --glob '*.tsx'

# Test: Verify the usage of useLocalPref hook with 'category.width'
rg "useLocalPref\\('category\\.width'" packages/desktop-client/src --glob '*.tsx'

Length of output: 1529

packages/desktop-client/src/components/settings/UI.tsx (2)

9-9: LGTM: New import for Text component.

The addition of the Text import is appropriate for use in the new Column component.


Line range hint 1-31: Summary: New Column component aligns well with PR objectives.

The introduction of the Column component enhances the settings UI structure, providing a reusable layout element that aligns with the PR's goal of improving the budget view's customizability. This component can be utilized to organize various settings, including the new display settings for category width.

The implementation is clean, follows good practices, and doesn't introduce any conflicts with existing code. It sets a good foundation for further UI enhancements in the settings area.

packages/desktop-client/src/components/budget/rollover/budgetsummary/ToBudget.tsx (1)

5-5: LGTM: New import for useLocalPref hook

The import statement for useLocalPref is correctly placed and necessary for the new functionality being introduced in this component.

packages/desktop-client/src/components/budget/BudgetTotals.tsx (2)

4-4: LGTM: Import statement for useLocalPref is correctly added.

The new import statement for useLocalPref is appropriately placed and necessary for the changes implemented in this component.


49-49: LGTM: categoryWidth is correctly applied to both View and Popover components.

The dynamic categoryWidth value is consistently used to replace the hardcoded values, allowing for user customization of the category column width.

To ensure that all instances of the hardcoded width have been replaced, please run the following verification script:

Also applies to: 82-82

✅ Verification successful

Verified: All hardcoded width values of 200 have been successfully replaced in BudgetTotals.tsx.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining hardcoded width values of 200 in BudgetTotals.tsx

# Test: Search for any remaining instances of width: 200 or width={200}
rg --type typescript 'width:\s*200|width=\{200\}' packages/desktop-client/src/components/budget/BudgetTotals.tsx

# If no results are found, all instances have been replaced successfully

Length of output: 149


Script:

#!/bin/bash
# Description: Check for any remaining hardcoded width values of 200 in BudgetTotals.tsx

# Test: Search for any remaining instances of width: 200 or width={200}
rg 'width:\s*200|width=\{200\}' packages/desktop-client/src/components/budget/BudgetTotals.tsx

# If no results are found, all instances have been replaced successfully

Length of output: 96

packages/desktop-client/src/components/budget/DynamicBudgetTable.tsx (3)

8-8: LGTM: Import statement for useLocalPref is correctly added.

The import statement for useLocalPref is properly placed and correctly references the hook from the parent directory.


Line range hint 1-161: Overall assessment: Changes successfully implement customizable category width.

The modifications in this file effectively introduce the customizable category width feature:

  1. The useLocalPref hook is correctly implemented to retrieve user preferences.
  2. Width calculations (numPossible, maxWidth) are updated to use the dynamic categoryWidth.
  3. Changes are well-integrated and localized, minimizing potential side effects.

These changes align with the PR objectives and address the issue of fixed category widths. The implementation appears solid, with only minor suggestions for improvement provided in the previous comments.

To ensure the changes don't introduce any unintended consequences, please:

  1. Thoroughly test the rendering and functionality of the budget table with various category width settings.
  2. Verify that the changes work well with different screen sizes and resolutions.
  3. Consider adding unit tests to cover the new logic for calculating table dimensions with customizable widths.

50-53: Verify rendering and functionality with customizable width.

The changes to numPossible and maxWidth calculations should allow the DynamicBudgetTableInner component to render correctly with the customizable category width. However, it's crucial to verify that these modifications don't negatively impact the rendering or functionality of the budget table.

Please run the following script to check for any potential issues in the rendering logic:

This script will help identify any remaining hardcoded width values, verify proper propagation of categoryWidth, and check for any outstanding TODOs or FIXMEs related to width calculations.

packages/desktop-client/src/components/settings/Format.tsx (1)

17-17: LGTM! Verify the imported Column component's interface.

The refactoring to import the Column component from a separate UI module is a good practice for code organization and reusability. This change aligns with the DRY (Don't Repeat Yourself) principle.

To ensure the imported Column component maintains the same interface and functionality, please run the following script:

This script will help verify that the Column component in the UI module has the same interface as the previously local one and that its usage in FormatSettings remains consistent.

packages/desktop-client/src/components/budget/SidebarCategory.tsx (1)

10-10: LGTM: Import statement for useLocalPref is correctly added.

The new import statement for useLocalPref is properly placed and follows good practices for code organization.

packages/desktop-client/src/components/budget/SidebarGroup.tsx (1)

6-6: LGTM: Import statement for useLocalPref is correctly added.

The import statement for the useLocalPref hook is properly placed and correctly references the hook's location.

packages/desktop-client/src/components/settings/index.tsx (2)

28-28: LGTM: Import statement for DisplaySettings.

The import statement for the new DisplaySettings component is correctly placed and follows the existing import pattern in the file.


179-179: LGTM: Addition of DisplaySettings component.

The DisplaySettings component is appropriately placed within the Settings component, grouped with other visual settings. This addition aligns with the PR objectives of introducing customizable category width settings.

To ensure the DisplaySettings component is correctly implemented, please run the following verification script:

packages/desktop-client/src/components/budget/BudgetTable.jsx (1)

Line range hint 4-4: LGTM: New hook import for local preferences.

The addition of the useLocalPref hook import is appropriate for implementing the customizable category width feature.

packages/desktop-client/src/components/budget/rollover/RolloverComponents.tsx (2)

8-8: LGTM: New hook import added correctly.

The useLocalPref hook is imported correctly from the appropriate relative path.


Line range hint 1-474: Overall assessment: Changes successfully implement customizable category width.

The modifications in this file effectively address the PR objective of making the width of the categories column customizable. Key points:

  1. The useLocalPref hook is correctly implemented to retrieve user preferences.
  2. The default width of 200 pixels is maintained when no custom value is set.
  3. The categoryWidth variable is consistently used in relevant components.

These changes provide a solution to the issue of category names not fitting within the fixed width, especially after importing budgets from nYNAB. The implementation aligns well with the described requirements and allows for future flexibility.

Suggestions for consideration:

  1. Add a brief comment explaining the purpose of the categoryWidth preference.
  2. Verify that all relevant occurrences of hardcoded width have been updated.

Great job on your first pull request! The changes are well-implemented and address the stated objectives effectively.

Comment on lines +16 to +28
const onBlur: HTMLProps<HTMLInputElement>['onBlur'] = event => {
if (document.hasFocus()) {
const value = parseInt(event.target.value);

if (Number.isInteger(value)) {
const clampedValue = Math.max(100, Math.min(1024, value));
setPrefWidth(clampedValue);
setTempWidth(clampedValue.toString());
} else {
setTempWidth(prefWidth.toString());
}
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider refactoring the onBlur handler for improved readability and reusability.

While the logic is correct, consider the following improvements:

  1. Extract the clamping logic into a separate function for reusability.
  2. Add explicit error handling for non-integer inputs.
  3. Consider using a custom hook to encapsulate this logic.

Here's a suggested refactoring:

const clampWidth = (value: number) => Math.max(100, Math.min(1024, value));

const useWidthInput = (initialWidth: number) => {
  const [width, setWidth] = useState(initialWidth);
  const [tempWidth, setTempWidth] = useState(initialWidth.toString());

  const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
    if (document.hasFocus()) {
      const value = parseInt(event.target.value, 10);
      if (Number.isInteger(value)) {
        const clampedValue = clampWidth(value);
        setWidth(clampedValue);
        setTempWidth(clampedValue.toString());
      } else {
        setTempWidth(width.toString());
      }
    }
  };

  return { width, tempWidth, setTempWidth, handleBlur };
};

// In your component:
const { width, tempWidth, setTempWidth, handleBlur } = useWidthInput(prefWidth);

This refactoring improves readability, reusability, and separation of concerns.

Comment on lines +30 to +68
return (
<Setting
primaryAction={
<View
style={{
flexDirection: 'column',
gap: '1em',
width: '100%',
}}
>
<Column title="Categories Width">
<Text>
<Trans>
Width of the categories column in pixels. Must be between
</Trans>
</Text>
<Input
value={tempWidth}
onChange={event => setTempWidth(event.target.value)}
onBlur={onBlur}
style={{
':hover': {
backgroundColor: themeStyle.buttonNormalBackgroundHover,
},
}}
/>
</Column>
</View>
}
>
<Text>
<Trans>
<strong>Display settings</strong> change how certain elements of the
interface are displayed.
</Trans>
</Text>
</Setting>
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider extracting styles and improving component structure.

The component structure is well-organized, but there are a few areas for improvement:

  1. Extract inline styles into a separate stylesheet or use styled-components for better maintainability.
  2. Consider breaking down the component into smaller, reusable parts.
  3. The use of Trans for internationalization is good, but ensure all user-facing strings are wrapped with it.

Here's a suggestion for extracting styles:

import styled from 'styled-components';

const StyledInput = styled(Input)`
  &:hover {
    background-color: ${props => props.theme.buttonNormalBackgroundHover};
  }
`;

const SettingContainer = styled(View)`
  flex-direction: column;
  gap: 1em;
  width: 100%;
`;

// Then in your JSX:
<SettingContainer>
  <Column title={<Trans>Categories Width</Trans>}>
    {/* ... */}
    <StyledInput
      value={tempWidth}
      onChange={event => setTempWidth(event.target.value)}
      onBlur={handleBlur}
    />
  </Column>
</SettingContainer>

This approach improves code readability and maintainability by separating concerns.

@@ -261,7 +263,7 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
placement="bottom start"
isOpen={budgetMenuOpen}
onOpenChange={() => setBudgetMenuOpen(false)}
style={{ width: 200 }}
style={{ width: categoryWidth }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Action Required: Hardcoded width detected in IncomeHeader.tsx

The search revealed that width: 200 is still hardcoded in the following file:

  • packages/desktop-client/src/components/budget/IncomeHeader.tsx

Please replace the hardcoded value with the categoryWidth variable to maintain consistency and support dynamic width adjustment.

🔗 Analysis chain

LGTM: Consistent usage of categoryWidth in Popover components.

The categoryWidth variable is correctly used to set the width of the Popover components, replacing the hardcoded value of 200. This change successfully implements the customizable width feature as per the PR objectives.

To ensure consistency across the codebase:

If the script returns any results, please review those occurrences to determine if they should also use the categoryWidth variable.

Also applies to: 392-392

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that all occurrences of hardcoded width 200 for categories have been replaced
rg --type typescript "width: 200" packages/desktop-client/src/components/budget

Length of output: 116


Script:

#!/bin/bash
# Corrected script to verify that all occurrences of hardcoded width 200 for categories have been replaced
rg --type tsx "width: 200" packages/desktop-client/src/components/budget

Length of output: 102


Script:

#!/bin/bash
# Verify that all occurrences of hardcoded width 200 for categories have been replaced using a glob pattern
rg --glob "*.tsx" "width: 200" packages/desktop-client/src/components/budget

Length of output: 163

@github-actions github-actions bot removed the Stale label Sep 27, 2024
Copy link
Contributor

github-actions bot commented Oct 4, 2024

👋 Hi! It looks like this PR has not had any changes for a week now. Would you like someone to review this PR? If so - please remove the "[WIP]" prefix from the PR title. That will let the community know that this PR is open for a review.

@github-actions github-actions bot added the Stale label Oct 4, 2024
Copy link
Contributor

This PR was closed because it has been stalled for 5 days with no activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants