App icon indicating copy to clipboard operation
App copied to clipboard

[HOLD for payment 2024-10-29] [$250] Import categories - Dropdown button does not match the selection in the dropdown list

Open IuliiaHerets opened this issue 1 year ago • 36 comments

If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!


Version Number: 9.0.45-2 Reproducible in staging?: Y Reproducible in production?: Y Email or phone of affected tester (no customers): [email protected] Issue reported by: Applause Internal Team

Action Performed:

  1. Go to staging.new.expensify.com
  2. Go to workspace settings > Categories.
  3. Click 3-dot menu > Import spreadsheet.
  4. Upload a csv containing two column data.
  5. Click on the dropdown of the first item.

Expected Result:

The selection in the dropdown should match what is displayed on the dropdown button.

Actual Result:

The dropdown button shows "Enabled", but the selection in the dropdown is "Ignore".

Workaround:

Unknown

Platforms:

  • [x] Android: Native
  • [x] Android: mWeb Chrome
  • [x] iOS: Native
  • [x] iOS: mWeb Safari
  • [x] MacOS: Chrome / Safari
  • [x] MacOS: Desktop

Screenshots/Videos

Bug6626304_1728235057248!Screenshot_2024-10-07_at_01 12 42

https://github.com/user-attachments/assets/48118e97-396a-46ef-a88e-e1e98b26c949

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021843456236485457533
  • Upwork Job ID: 1843456236485457533
  • Last Price Increase: 2024-10-08
  • Automatic offers:
    • ZhenjaHorbach | Reviewer | 104404493
    • Nodebrute | Contributor | 104404495
Issue OwnerCurrent Issue Owner: @kadiealexander

IuliiaHerets avatar Oct 06 '24 19:10 IuliiaHerets

Triggered auto assignment to @kadiealexander (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

melvin-bot[bot] avatar Oct 06 '24 19:10 melvin-bot[bot]

We think that this bug might be related to #wave-control

IuliiaHerets avatar Oct 06 '24 19:10 IuliiaHerets

@kadiealexander FYI I haven't added the External label as I wasn't 100% sure about this issue. Please take a look and add the label if you agree it's a bug and can be handled by external contributors

IuliiaHerets avatar Oct 06 '24 19:10 IuliiaHerets

Edited by proposal-police: This proposal was edited at 2024-10-06 20:13:28 UTC.

Proposal

Please re-state the problem that we are trying to solve in this issue.

Dropdown button does not match the selection in the dropdown list

What is the root cause of that problem?

This issue occurs not only with categories but also with tags. In this case, the defaultSelectedIndex will return -1 if the index is not found. https://github.com/Expensify/App/blob/6d8e739f7b1c286ae65565a6689b27b5983fe48a/src/components/ImportColumn.tsx#L165 And then we pass this defaultSelectedIndex here, which is incorrect we should pass index 0 which is index of ignore https://github.com/Expensify/App/blob/6d8e739f7b1c286ae65565a6689b27b5983fe48a/src/components/ImportColumn.tsx#L204

What changes do you think we should make in order to solve the problem?

In cases where the defaultSelectedIndex is -1 we should pass 0 here https://github.com/Expensify/App/blob/6d8e739f7b1c286ae65565a6689b27b5983fe48a/src/components/ImportColumn.tsx#L204

We can do something like this (pseudo-code)

    const defaultSelectedIndex = columnRoles.findIndex((item) => item.value === colName);
    const finalIndex = defaultSelectedIndex !== -1 ? defaultSelectedIndex : 0;

and then we can pass this finalIndex here https://github.com/Expensify/App/blob/6d8e739f7b1c286ae65565a6689b27b5983fe48a/src/components/ImportColumn.tsx#L204

Some cleanup may be required, which we can address in the PR. Result

https://github.com/user-attachments/assets/19886efd-dad6-4280-aaf7-56a0888522a5

[!NOTE]
There are multiple ways to achieve the same result, but I'm keeping the proposal simple by avoiding excessive options.

What alternative solutions did you explore? (Optional)

Even though the index of 'ignore' is consistently 0 across all pages, we can implement additional checks to make this more error-proof.

    const defaultSelectedIndex = columnRoles.findIndex((item) => item.value === colName);
    const finalIndex = defaultSelectedIndex !== -1 ? defaultSelectedIndex : columnRoles.findIndex(item => item.value === 'ignore');

Nodebrute avatar Oct 06 '24 20:10 Nodebrute

Proposal Updated Added POC

Nodebrute avatar Oct 06 '24 20:10 Nodebrute

Proposal

Please re-state the problem that we are trying to solve in this issue.

Dropdown button does not match the selection in the dropdown list

What is the root cause of that problem?

The dropdown button highlight is selected based on the isSelected prop:

https://github.com/Expensify/App/blob/134bbd0faf3171e30c0d7bd1349e05de5d5adbba/src/components/ImportColumn.tsx#L155-L160

But when we get the defaultSelectedIndex, we are essentially comparing against the colName which is derived from column hence we always get -1 as the return value. This will display the last option in the list as the header value of the dropdown.

https://github.com/Expensify/App/blob/6d8e739f7b1c286ae65565a6689b27b5983fe48a/src/components/ImportColumn.tsx#L165

the reason this check fails is that the values of colName are:

Screenshot 2024-10-07 at 3 03 23 AM

Hence they will never match with the values of columnRoles:

Screenshot 2024-10-07 at 3 01 59 AM

What changes do you think we should make in order to solve the problem?

We should instead get the value from options/ columnRoles itself by checking if isSelected is set to true and if yes them we should show that option as the header:

    const defaultSelectedIndex = options.findIndex((item) => item.isSelected === true)

We should fix this in other places where csv import is used, for cases where none is selected we shouldn't display any value for the header, we should consult with design team for the exact behaviour for this case

https://github.com/user-attachments/assets/d44301c9-3c50-44f9-84d6-859610b5a587

What alternative solutions did you explore? (Optional)

twilight2294 avatar Oct 06 '24 21:10 twilight2294

Proposal

Please re-state the problem that we are trying to solve in this issue.

Import categories - Dropdown button does not match the selection in the dropdown list

What is the root cause of that problem?

This bug happens with the column that returns the columnName as empty in the default case here

It leads the defaultSelectedIndex to be -1 which causes the display text in the dropdown button to be different from the selected option in the drop-down menu https://github.com/Expensify/App/blob/7981265dc14bc9cb99b512baddbb027446568fcf/src/components/ImportColumn.tsx#L165

What changes do you think we should make in order to solve the problem?

For the default case, we should return CONST.CSV_IMPORT_COLUMNS.IGNORE here instead of an empty string.

default:
    attribute = CONST.CSV_IMPORT_COLUMNS.IGNORE;
    break;

https://github.com/Expensify/App/blob/7981265dc14bc9cb99b512baddbb027446568fcf/src/components/ImportColumn.tsx#L114-L116

What alternative solutions did you explore? (Optional)

mkzie2 avatar Oct 07 '24 09:10 mkzie2

Job added to Upwork: https://www.upwork.com/jobs/~021843456236485457533

melvin-bot[bot] avatar Oct 08 '24 00:10 melvin-bot[bot]

Triggered auto assignment to Contributor-plus team member for initial proposal review - @ZhenjaHorbach (External)

melvin-bot[bot] avatar Oct 08 '24 00:10 melvin-bot[bot]

This is a wave-control project, moving.

trjExpensify avatar Oct 08 '24 01:10 trjExpensify

I will check proposals today or tomorrow !

ZhenjaHorbach avatar Oct 08 '24 10:10 ZhenjaHorbach

@Nodebrute @twilight294 @mkzie2 Thanks for proposals !

@Nodebrute @mkzie2 Your proposals look similar (Have the same result) But I'm not sure that we should stick to a specific value Because if this value will be missing in a list, issue will be reproduced I know that now we have Ignore on every Options list at the moment (But I won't be surprised if something changes in the future) So I would prefer some more flexible solution

@twilight294 Your proposal looks promising But unfortunately it doesn't work for me Could you please provide more code?

ZhenjaHorbach avatar Oct 09 '24 20:10 ZhenjaHorbach

@ZhenjaHorbach, @mkzie2's solution will not work. You can try importing this file in the tags import section, and you'll see that the error will still be reproducible with the GL code value. Categories-2024-09-10 17_10_20.413.csv

Nodebrute avatar Oct 09 '24 20:10 Nodebrute

@mkzie2's solution will not work because, in this case, the colName will return glcode. https://github.com/Expensify/App/blob/d6d300798d9430b89d9ac11dea01b10f7c1ff779/src/components/ImportColumn.tsx#L34 And in this case, when we don't pass 'glcode' in the tags, it will return -1, thus reproducing the error. https://github.com/Expensify/App/blob/d6d300798d9430b89d9ac11dea01b10f7c1ff779/src/components/ImportColumn.tsx#L165

@ZhenjaHorbach I have proposed two solutions. The first is to fallback to the 0 index. Let’s assume we don’t have ignore in the future, which I believe will never happen😅, but at the very least, we will have a default value at the 0 index. So, instead of falling back to ignore, we can always fallback to the 0 index.

My second solution, where we can find the index of ignore instead of falling back to 0, is quite reliable. When we set the spreadsheet data, we use ignore, so ignore will remain our default for a long time. https://github.com/Expensify/App/blob/d6d300798d9430b89d9ac11dea01b10f7c1ff779/src/libs/actions/ImportSpreadsheet.ts#L13

Nodebrute avatar Oct 09 '24 20:10 Nodebrute

@ZhenjaHorbach Sorry for the message overload! I just checked OD as well, and it seems ignore is the default for everything there too. Let me know what you think about the points above. Screenshot 2024-10-10 at 1 57 40 AM

Nodebrute avatar Oct 09 '24 21:10 Nodebrute

@ZhenjaHorbach Here is why I propose adding the ignore as a fallback in the findColumnName function.

When we import a CSV file, we save the spreadsheet data, and all column names are ignore by default. Then the column name will be updated based on the value in findColumnName function.

https://github.com/Expensify/App/blob/f0be8a731dc0832827dbd14d23fd49b332ff275e/src/libs/actions/ImportSpreadsheet.ts#L12-L15

It will not update in the case empty string is returned because we already have the check here. But the defaultSelectedIndex is also used to focus and display the correct column value then it makes sense to return ignore by default https://github.com/Expensify/App/blob/f0be8a731dc0832827dbd14d23fd49b332ff275e/src/components/ImportColumn.tsx#L167-L174

mkzie2 avatar Oct 10 '24 04:10 mkzie2

@twilight294 Your proposal looks promising But unfortunately it doesn't work for me Could you please provide more code?

oh my bad, actually we have to add extra type prop to DropdownOption here, Below is the test branch and a test csv with categories, do let me know if you have any more doubts:

CSV: Categories-2024-10-10 05_30_44.389.csv

Test PR: - https://github.com/Expensify/App/pull/50542

twilight2294 avatar Oct 10 '24 05:10 twilight2294

@twilight294 in your test branch you are using 0 as fallback, similar to my proposal.

Cc: @ZhenjaHorbach

Nodebrute avatar Oct 10 '24 09:10 Nodebrute

@mkzie2's solution will not work because, in this case, the colName will return glcode.

https://github.com/Expensify/App/blob/d6d300798d9430b89d9ac11dea01b10f7c1ff779/src/components/ImportColumn.tsx#L34

And in this case, when we don't pass 'glcode' in the tags, it will return -1, thus reproducing the error. https://github.com/Expensify/App/blob/d6d300798d9430b89d9ac11dea01b10f7c1ff779/src/components/ImportColumn.tsx#L165

@ZhenjaHorbach I have proposed two solutions. The first is to fallback to the 0 index. Let’s assume we don’t have ignore in the future, which I believe will never happen😅, but at the very least, we will have a default value at the 0 index. So, instead of falling back to ignore, we can always fallback to the 0 index.

My second solution, where we can find the index of ignore instead of falling back to 0, is quite reliable. When we set the spreadsheet data, we use ignore, so ignore will remain our default for a long time.

https://github.com/Expensify/App/blob/d6d300798d9430b89d9ac11dea01b10f7c1ff779/src/libs/actions/ImportSpreadsheet.ts#L13

Hmmmm Yes Your alternative solution looks interesting And I think it makes sense to use ignore as the default value in case of something

ZhenjaHorbach avatar Oct 11 '24 14:10 ZhenjaHorbach

I think this proposal make sense in which many details are taken into account

So I'm happy to go with this proposal 🎀👀🎀 C+ reviewed

ZhenjaHorbach avatar Oct 11 '24 14:10 ZhenjaHorbach

Triggered auto assignment to @mjasikowski, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

melvin-bot[bot] avatar Oct 11 '24 14:10 melvin-bot[bot]

@ZhenjaHorbach we should always compare with options and not columnRoles, as outlined in my proposal here.

c.c. @mjasikowski

twilight2294 avatar Oct 11 '24 14:10 twilight2294

@ZhenjaHorbach let's go ahead with @Nodebrute's proposal

mjasikowski avatar Oct 14 '24 06:10 mjasikowski

📣 @ZhenjaHorbach 🎉 An offer has been automatically sent to your Upwork account for the Reviewer role 🎉 Thanks for contributing to the Expensify app!

Offer link Upwork job

melvin-bot[bot] avatar Oct 14 '24 06:10 melvin-bot[bot]

📣 @Nodebrute 🎉 An offer has been automatically sent to your Upwork account for the Contributor role 🎉 Thanks for contributing to the Expensify app!

Offer link Upwork job Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑‍💻 Keep in mind: Code of Conduct | Contributing 📖

melvin-bot[bot] avatar Oct 14 '24 06:10 melvin-bot[bot]

@ZhenjaHorbach Can you please check again? We should update findColumnName function by returning the default value correctly instead of having a fallback like the selected proposal, it doesn't fix the RCA. I also have an explanation here

const defaultSelectedIndex = columnRoles.findIndex((item) => item.value === colName);
const finalIndex = defaultSelectedIndex !== -1 ? defaultSelectedIndex : columnRoles.findIndex(item => item.value === 'ignore');

mkzie2 avatar Oct 14 '24 09:10 mkzie2

@mkzie2, your proposal didn't work.

@ZhenjaHorbach, @mkzie2's solution will not work. You can try importing this file in the tags import section, and you'll see that the error will still be reproducible with the GL code value. Categories-2024-09-10 17_10_20.413.csv

Here are the steps to test your proposal. You'll see that it doesn't fix the problem.

Nodebrute avatar Oct 14 '24 14:10 Nodebrute

Pr will be ready in few hours

Nodebrute avatar Oct 15 '24 22:10 Nodebrute

Reviewing label has been removed, please complete the "BugZero Checklist".

melvin-bot[bot] avatar Oct 22 '24 04:10 melvin-bot[bot]

The solution for this issue has been :rocket: deployed to production :rocket: in version 9.0.51-4 and is now subject to a 7-day regression period :calendar:. Here is the list of pull requests that resolve this issue:

  • https://github.com/Expensify/App/pull/50726

If no regressions arise, payment will be issued on 2024-10-29. :confetti_ball:

For reference, here are some details about the assignees on this issue:

melvin-bot[bot] avatar Oct 22 '24 04:10 melvin-bot[bot]