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

fix: #842 - "undefined" value on dashboard assets graph #844

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

AurelienConte
Copy link

@AurelienConte AurelienConte commented Jun 7, 2024

Fixing issue of FractionalPart displaying "undefined" in the pie chart element used to display assets and debts on the dashboard

EDIT : Please, do not hesitate to tell me about the testing part, i'm not familiar with ruby and tools in this ecosystem. I'm still learning and maybe i used them in a not proper way !

assert_equal expected_value, extracted_value, "The pie chart value is not displayed correctly"
end

end
Copy link
Collaborator

@zachgoll zachgoll Jun 7, 2024

Choose a reason for hiding this comment

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

Great idea to add these tests! A few ideas to make this test a bit more resilient:

  • We should try and be less specific with our selectors here. I'd go ahead and add an id or data-id on the specific element that you're looking to test so that when classes change in the future (which they likely will), this test will not break.
  • I think if you want to write a system test like this, it should be in a file called test/system/dashboard_test.rb. That said, since this is specific to the formatting of a monetary value which is provided by value_groups_helper.rb, it might be best to test this directly in test/helpers/value_groups_helper_test.rb

This is a pretty tricky one as it deals with the formatting of a currency. Since we support multi-currency apps, it appears that the problem here may exist in the pie_chart_controller.js, which relies on the values to be in USD.

#currencyValue(datum) {
const formattedValue = Intl.NumberFormat(undefined, {
style: "currency",
currency: datum.currency,
currencyDisplay: "narrowSymbol",
}).format(datum.value);
const firstDigitIndex = formattedValue.search(/\d/);
const currencyPrefix = formattedValue.substring(0, firstDigitIndex);
const mainPart = formattedValue.substring(firstDigitIndex);
const [integerPart, fractionalPart] = mainPart.split(".");
return `<p class="text-gray-500 -space-x-0.5">${currencyPrefix}<span class="text-xl text-gray-900 font-medium">${integerPart}</span>.${fractionalPart}</p>`;
}

I think the change that we should consider making is removing or altering the #currencyValue method from pie_chart_controller.js. This method relies on the decimal separator always being a . which will not apply for all currencies. Switching this to , will then cause the opposite problem. I'm not sure what the best solution here is, but my guess is that it would be easier to pass the Stimulus controller an already-formatted currency value so that we can leverage our robust collection of Money::Currency objects on the backend.

Copy link
Author

Choose a reason for hiding this comment

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

I have made the logic in the backend to generate the value but i stick with a problem. The display is not really looking like time series chart is doing right now ( which is better ! )

Pie chart display :
image

TimeSeries chart display : ( the title part )
image

I can't find a way to display in gray the symbol, i don't known if using the format parameter of format_money function i use is a good approach to fix this problem..

I'm pushing my current changes, if you have some advice i will be happy !

Copy link
Collaborator

Choose a reason for hiding this comment

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

@AurelienConte if I'm following you correctly here, I believe this is expected behavior.

The time series graph will show net worth (assets - liabilities) while the pie chart here is showing assets only.

.to_json

total = values.sum { |child| child[:value] }
formatted_total = format_money(total, precision: 2, unit: value_group.sum.currency.symbol, separator: ".", delimiter: ",")
Copy link
Collaborator

@zachgoll zachgoll Jun 10, 2024

Choose a reason for hiding this comment

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

I think we're getting closer here, but we cannot rely on the separator and delimiter being fixed values. These will be reversed in some cases depending on the currency that is being formatted.

A potential data structure that we could pass to the frontend could be:

{
  # ...other parts
  cents_str: child.sum.cents_str,
  dollar_str: format_money_without_symbol(child.sum, precision: 0),
  currency_symbol: child.sum.currency.symbol
}

This allows us to retain the original value while also getting the individual parts of the value that can be independently displayed.

Check out these two methods for reference:

maybe/lib/money.rb

Lines 36 to 46 in 87a40aa

def cents_str(precision = currency.default_precision)
format_str = "%.#{precision}f"
amount_str = format_str % amount
parts = amount_str.split(currency.separator)
if parts.length < 2
""
else
parts.last.ljust(precision, "0")
end
end

def format_money_without_symbol(number_or_money, options = {})
money = Money.new(number_or_money)
options.reverse_merge!(money.default_format_options)
ActiveSupport::NumberHelper.number_to_delimited(money.amount.round(options[:precision] || 0), { delimiter: options[:delimiter], separator: options[:separator] })
end

@zachgoll
Copy link
Collaborator

@AurelienConte do you plan to continue work on this? No worries either way, just let me know!

@AurelienConte
Copy link
Author

Sorry i was on vacation, I just come back today at work !
I plan to come back on the pull request tomorrow or Wednesday 😄

@zachgoll
Copy link
Collaborator

@AurelienConte sounds great!

…return also how the symbol should be displayed
currency: {
iso_code: child.sum.currency.iso_code,
symbol: child.sum.currency.symbol,
displayed_before_value: child.sum.currency.default_format.start_with?("%u")
Copy link
Author

Choose a reason for hiding this comment

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

i have added this value to known how to display the symbol in the front like :

image

And

image

Where sometimes it is on the front of the value and sometimes in the back

value: total_value,
value_str: {
main_part: main_part,
fractional_part: fractional_part
Copy link
Author

Choose a reason for hiding this comment

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

i have choose terms more generic like main_part and fractional_part, do you think this is good or you want to stick with something like dollars_str and cents_str ?

@AurelienConte
Copy link
Author

I made changes to the feat, if you think this is good to you i will start modifying my tests to match the code changes

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

Successfully merging this pull request may close these issues.

None yet

2 participants