-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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: optimistically add personal details #22904
Conversation
src/libs/actions/Policy.js
Outdated
displayName: login, | ||
}; | ||
|
||
policyPersonalDetails.successData[accountID] = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this cause a flicker?
- Optimistically set account
- On success, remove account
- On success (server response), add account (probably another account)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The swapping of the optimistic data with the server data on success should happen within the same rendering cycle.
I did not observe a flickering in the sense that members are removed and then reappear.
Avatars and display names, however, can update upon retrieving the server data. This behavior is consistent with other instances where one adds a user, for example if you create a report with or assign a task to a user that you have not interacted with yet.
The reason is that the optimistically set data is derived from the search result, and the search result is not an accurate depiction as no backend calls are made. In an ideal situation the search result is accurate and contains all information, but there may be performance/UX/privacy reasons why this was not pursued.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that when creating a report with a new user, both the optimistic user and the BE user remain in personalDetailsList
.
If you subsequently search for the user, you will see 2 search results instead of 1.
My addition of policyPersonalDetails.successData[accountID] = null;
prevents such problem by ensuring the optimistic user is cleaned up. So I think in other parts of the codebase a similar cleanup mechanism needs to be put in place, however this is outside the scope of this issue (in my opinion).
Alternatively, we could add a boolean flag to the optimistic user and filter these out in the search results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, same thing goes for policyMembers_
We will have redundant members. I think we can keep that outside the scope as well. Let's just make sure we have optimistic data for new non existing members.
Reviewer Checklist
Screenshots/VideosWebweb.mp4Mobile Web - Chromemweb-chrome.mp4Mobile Web - Safarimweb-safari.mp4Desktopdesktop.mp4iOSios.mp4Androidandroid.mp4 |
src/libs/actions/Policy.js
Outdated
* @param {Array<number>} accountIDs Array of user accountIDs | ||
* @returns {Object} - object with optimisticData, successData and failureData (object of personal details objects) | ||
*/ | ||
function buildPolicyPersonalDetails(logins, accountIDs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function name is not the most accurate, this data is not explicit to policies. Can we move this function to somewhere more fitting? e.g. PersonalDetails.js
. Also I think we should indicate that the function will only return onyx data for non existing users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have:
- Moved it to
PersonalDetailsUtils.js
. - Renamed it to
getNewPersonalDetailsOnyxData
. - Updated the JSDoc.
- Made a small modification to ensure compatibility with
PersonalDetailsUtils.js
, wherepersonalDetails
is an array instead of an object. - It now returns complete Onyx data (including onyxMethod and key) instead of just the personal detail objects. This makes it consistent with other functions that have "OnyxData" in their name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move that to PersonalDetails
instead? Having personalDetails
as an object is faster to access.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would moving it to PersonalDetails.js
be semantically correct? It's placed in the actions/ folder and primarily contains functions triggering API calls, although also a few helper functions so it might be reasonable.
Yes iterating over the array is less efficient. It may have been done as a speed optimization if the other util functions are called often, so it's more efficient to cast it to an array at Onyx.connect instead of within the util function (executed many times). I would therefore be hesitant to change it to an object and put an extra cast to array inside the other existing functions, without further testing the performance implications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should add another value to PersonalDetailsUtils
? keeping personalDetails
as array and adding allPersonalDetails
as object.
Then we make make a follow up PR to rewrite the util functions that use the array to use the object and remove the array variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems like a good way forward. I have committed the change and will work on the refactor in a separate PR.
src/libs/PersonalDetailsUtils.js
Outdated
displayName: login, | ||
}; | ||
|
||
// Cleanup the optimistic user to ensure it does not permanently persist |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this comment is incomplete. Can you please indicate that this is done to prevent duplicated entries since the server will return other personal details with the correct account ids.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I've expanded it. Let me know what you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 🚀
@yuwenmemon Looking forward to your review. Please keep in mind it is day 8 at this point, thank you. I will subsequently work on the follow-up PR (i.e. refactor to make use of the personal details object). |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
const accountIDs = _.values(invitedEmailsToAccountIDs); | ||
const newPersonalDetailsOnyxData = PersonalDetailsUtils.getNewPersonalDetailsOnyxData(logins, accountIDs); | ||
|
||
// create onyx data for policy expense chats for each new member | ||
const membersChats = createPolicyExpenseChats(policyID, invitedEmailsToAccountIDs, betas); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems we're doing same work in different issues.
Is it fine to revert this PR and apply changes in #22410?
We should add members optimistically to policy expense chat as well (if policyExpenseChat
beta enabled), not only to workspace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc: @rezkiy37 @madmax330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add members optimistically to policy expense chat as well (if policyExpenseChat beta enabled), not only to workspace.
@0xmiroslav can you update your PR to do this?
Then the two would complement each other right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#22410 is more optimized code as reusing optimistic members from workspace chat.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, go ahead and resolve the conflict in #22410 and we will review.
🚀 Deployed to staging by https://github.com/yuwenmemon in version: 1.3.44-0 🚀
|
🚀 Deployed to production by https://github.com/marcaaron in version: 1.3.44-2 🚀
|
🚀 Deployed to staging by https://github.com/yuwenmemon in version: 1.3.45-0 🚀
|
🚀 Deployed to production by https://github.com/mountiny in version: 1.3.45-7 🚀
|
Details
When inviting members to a Workspace, optimistically add the personal details where non-existent.
Fixed Issues
$ #22442
PROPOSAL: #22442 (comment)
Tests
Offline tests
QA Steps
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodWaiting for Copy
label for a copy review on the original GH to get the correct copy.STYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)/** comment above it */
this
properly so there are no scoping issues (i.e. foronClick={this.submit}
the methodthis.submit
should be bound tothis
in the constructor)this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Web
Web.Screen.Recording.2023-07-14.at.15.55.27.mp4
Mobile Web - Chrome
mWeb.Chrome.Screen.Recording.2023-07-14.at.16.09.52.mp4
Mobile Web - Safari
mWeb.Safari.Screen.Recording.2023-07-14.at.15.58.30.mp4
Desktop
Desktop.Screen.Recording.2023-07-14.at.16.01.31.mp4
iOS
Native.ios.Screen.Recording.2023-07-14.at.15.52.18.mp4
Android
Native.android.Screen.Recording.2023-07-14.at.19.12.55.mp4