Skip to content

fix: SavePreferences being called multiple times and causing issues #35904

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

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

Conversation

MartinSchoeler
Copy link
Member

@MartinSchoeler MartinSchoeler commented Apr 29, 2025

The preferences are being saved multiple times when you press save, this can cause some issues, like when selecting a new language, the page tries to reset the forms while the promise is being processed, causing the language to be saved as the previous value

Issue(s)

CORE-1106

Steps to test or reproduce

  1. Go to user preferences
  2. Change the language
  3. check if the language being used is the same as the one selected

This issue happened more consistently with the Portuguese and Brazilan Portuguese languages

Further comments


This pull request addresses an issue where the SavePreferences function was being called multiple times, leading to potential problems. The changes include the introduction of a new React hook, useSavePreferences, which is designed to handle the saving of user account preferences. This hook uses useMutation from @tanstack/react-query to interact with the /v1/users.setPreferences API endpoint, processes specific fields like highlights and dontAskAgainList based on dirty fields, and provides user feedback through toast messages.

Additionally, a new test suite for the useSavePreferences hook has been added using React Testing Library and Jest to ensure that the hook correctly triggers the users.setPreferences API endpoint when invoked. The preference saving logic in the AccountPreferencesPage component has been refactored to use this new custom hook, simplifying the component and improving code organization by centralizing the saving mechanism.

Copy link
Contributor

dionisio-bot bot commented Apr 29, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

Copy link

changeset-bot bot commented Apr 29, 2025

🦋 Changeset detected

Latest commit: 5910dc5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 36 packages
Name Type
@rocket.chat/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/freeswitch Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/stream-hub-service Patch
@rocket.chat/license Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/models Patch
@rocket.chat/network-broker Patch
@rocket.chat/mock-providers Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-video-conf Patch
@rocket.chat/ui-voip Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/instance-status Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

kodus-ai bot commented Apr 29, 2025

Code Review Completed! 🔥

The code review was successfully completed based on your current configurations.

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Security
Code Style
Kody Rules
Refactoring
Error Handling
Maintainability
Potential Issues
Documentation And Comments
Performance And Optimization
Breaking Changes

Access your configuration settings here.

Copy link

codecov bot commented Apr 29, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 61.26%. Comparing base (26461ca) to head (5910dc5).

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #35904      +/-   ##
===========================================
- Coverage    61.26%   61.26%   -0.01%     
===========================================
  Files         3164     3164              
  Lines        74757    74757              
  Branches     16689    16689              
===========================================
- Hits         45801    45800       -1     
- Misses       25850    25852       +2     
+ Partials      3106     3105       -1     
Flag Coverage Δ
e2e 58.02% <ø> (-0.01%) ⬇️
unit 75.11% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

github-actions bot commented Apr 29, 2025

PR Preview Action v1.6.1

🚀 View preview at
https://RocketChat.github.io/Rocket.Chat/pr-preview/pr-35904/

Built to branch gh-pages at 2025-05-05 18:16 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Copy link

kodus-ai bot commented Apr 29, 2025

Kody Review Complete

Great news! 🎉
No issues were found that match your current review configurations.

Keep up the excellent work! 🚀

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Security
Code Style
Kody Rules
Refactoring
Error Handling
Maintainability
Potential Issues
Documentation And Comments
Performance And Optimization
Breaking Changes

Access your configuration settings here.

Copy link

kodus-ai bot commented Apr 29, 2025

Kody Review Complete

Great news! 🎉
No issues were found that match your current review configurations.

Keep up the excellent work! 🚀

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Security
Code Style
Kody Rules
Refactoring
Error Handling
Maintainability
Potential Issues
Documentation And Comments
Performance And Optimization
Breaking Changes

Access your configuration settings here.

@MartinSchoeler MartinSchoeler added this to the 7.7.0 milestone Apr 29, 2025
@MartinSchoeler MartinSchoeler marked this pull request as ready for review April 30, 2025 14:12
@MartinSchoeler MartinSchoeler requested a review from a team as a code owner April 30, 2025 14:12
Copy link

kodus-ai bot commented May 5, 2025

Code Review Completed! 🔥

The code review was successfully completed based on your current configurations.

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Security
Code Style
Kody Rules
Refactoring
Error Handling
Maintainability
Potential Issues
Documentation And Comments
Performance And Optimization
Breaking Changes

Access your configuration settings here.

Comment on lines -37 to +34
const setPreferencesEndpoint = useEndpoint('POST', '/v1/users.setPreferences');
const setPreferencesAction = useMutation({
mutationFn: setPreferencesEndpoint,
onSuccess: () => {
dispatchToastMessage({ type: 'success', message: t('Preferences_saved') });
},
onError: (error) => {
dispatchToastMessage({ type: 'error', message: error });
},
onSettled: () => reset(currentData),
});

const handleSaveData = async (formData: AccountPreferencesData) => {
const { highlights, dontAskAgainList, ...data } = getDirtyFields(formData, dirtyFields);
if (highlights || highlights === '') {
Object.assign(data, {
highlights:
typeof highlights === 'string' &&
highlights
.split(/,|\n/)
.map((val) => val.trim())
.filter(Boolean),
});
}

if (dontAskAgainList) {
const list =
Array.isArray(dontAskAgainList) && dontAskAgainList.length > 0
? dontAskAgainList.map(([action, label]) => ({ action, label }))
: [];
Object.assign(data, { dontAskAgainList: list });
}

setPreferencesAction.mutateAsync({ data });
};
const handleSaveData = useSavePreferences({ dirtyFields, currentData, reset });
Copy link
Member

Choose a reason for hiding this comment

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

What changed in the logic here besides moving to a hook?

currentData: AccountPreferencesData;
};

export const useSavePreferences = ({ dirtyFields, currentData, reset }: useSavePreferencesProps) => {
Copy link
Member

Choose a reason for hiding this comment

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

I would advise against refactoring the logic into a separate hook in a fix, unless it would be used in another component. Makes it hard to understand what the root cause and fix was.

Comment on lines +9 to +21
describe('useSavePreferences', () => {
it('should call setPreferencesEndpoint with correct data', async () => {
const dirtyFields = { language: true };
const { result } = renderHook(() => useSavePreferences({ dirtyFields, reset: jest.fn(), currentData: {} }), {
wrapper: mockAppRoot().withEndpoint('POST', '/v1/users.setPreferences', mockSetPreferencesEndpoint).build(),
});

const formData: AccountPreferencesData = { language: 'en' };
await waitFor(() => result.current(formData));

expect(mockSetPreferencesEndpoint).toHaveBeenCalledTimes(1);
});
});
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be an e2e test instead. I wasn't able to make this test fail, even by copying the old logic into the new hook.

Copy link
Member

@dougfabris dougfabris left a comment

Choose a reason for hiding this comment

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

this is a refactor, the fix probably won't need this amount of code. I'd suggest separating it into a brand new PR in order to have a isolated fix

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.

3 participants