-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Move policy employee list logic to ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST
#10461
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
Changes from all commits
60c3bec
097f78e
0712c4a
c134503
2a7ef48
94f4aee
cd5e71f
f775f69
78730c6
f95bd12
ca233bf
f05e06c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,19 +34,18 @@ Onyx.connect({ | |
| }); | ||
|
|
||
| /** | ||
| * Simplifies the employeeList response into an object containing an array of emails | ||
| * Simplifies the employeeList response into an object mapping employee email to a default employee list entry | ||
| * | ||
| * @param {Object} employeeList | ||
| * @returns {Array} | ||
| * @returns {Object} | ||
| */ | ||
| function getSimplifiedEmployeeList(employeeList) { | ||
| const employeeListEmails = _.chain(employeeList) | ||
| return _.chain(employeeList) | ||
| .pluck('email') | ||
| .flatten() | ||
| .unique() | ||
| .reduce((map, email) => ({...map, [email]: {}}), {}) | ||
| .value(); | ||
|
|
||
| return employeeListEmails; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -92,7 +91,6 @@ function getSimplifiedPolicyObject(fullPolicyOrPolicySummary, isFromFullPolicy) | |
| // "GetFullPolicy" and "GetPolicySummaryList" returns different policy objects. If policy is retrieved by "GetFullPolicy", | ||
| // avatarUrl will be nested within the key "value" | ||
| avatarURL: fullPolicyOrPolicySummary.avatarURL || lodashGet(fullPolicyOrPolicySummary, 'value.avatarURL', ''), | ||
| employeeList: getSimplifiedEmployeeList(lodashGet(fullPolicyOrPolicySummary, 'value.employeeList')), | ||
| customUnit: customUnitSimplified, | ||
| }; | ||
| } | ||
|
|
@@ -143,14 +141,16 @@ function create(name = '') { | |
| Report.fetchChatReportsByIDs([response.policy.chatReportIDAdmins, response.policy.chatReportIDAnnounce, response.ownerPolicyExpenseChatID]); | ||
|
|
||
| // We are awaiting this merge so that we can guarantee our policy is available to any React components connected to the policies collection before we navigate to a new route. | ||
| return Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${response.policyID}`, { | ||
| employeeList: getSimplifiedEmployeeList(response.policy.employeeList), | ||
| id: response.policyID, | ||
| type: response.policy.type, | ||
| name: response.policy.name, | ||
| role: CONST.POLICY.ROLE.ADMIN, | ||
| outputCurrency: response.policy.outputCurrency, | ||
| }); | ||
| return Promise.all( | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${response.policyID}`, { | ||
| id: response.policyID, | ||
| type: response.policy.type, | ||
| name: response.policy.name, | ||
| role: CONST.POLICY.ROLE.ADMIN, | ||
| outputCurrency: response.policy.outputCurrency, | ||
| }), | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${response.policyID}`, getSimplifiedEmployeeList(response.policy.employeeList)), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it necessary to have both of these inside the promise.all? I don't think it matters when the member list is merged, does it? It also doesn't seem like it matters when the policy object is merged. The only time the promise returned from
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The policy data would need to be merged otherwise the workspace page would briefly open as "Not Found" until the Onyx update finishes. I included the members list here also just to be safe. The functionality here is very temporary since it'll be replaced by incoming workspace refactors so I wouldn't lose too much sleep optimizing it.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, while I am fine not doing anything since it's only temporary, I do think it's important to always make clear and appropriate choices with code, regardless of how long it's going to live. |
||
| ); | ||
| }) | ||
| .then(() => Promise.resolve(lodashGet(res, 'policyID'))); | ||
| } | ||
|
|
@@ -259,10 +259,8 @@ function loadFullPolicy(policyID) { | |
| return; | ||
| } | ||
|
|
||
| Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, { | ||
| ...allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`], | ||
| ...getSimplifiedPolicyObject(policy, true), | ||
| }); | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, getSimplifiedPolicyObject(policy, true)); | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policy.id}`, getSimplifiedEmployeeList(lodashGet(policy, 'value.employeeList', {}))); | ||
| }); | ||
| } | ||
|
|
||
|
|
@@ -291,14 +289,9 @@ function removeMembers(members, policyID) { | |
| return; | ||
| } | ||
|
|
||
| const key = `${ONYXKEYS.COLLECTION.POLICY}${policyID}`; | ||
|
|
||
| // Make a shallow copy to preserve original data and remove the members | ||
| const policy = _.clone(allPolicies[key]); | ||
| policy.employeeList = _.without(policy.employeeList, ...members); | ||
|
|
||
| // Optimistically remove the members from the policy | ||
| Onyx.set(key, policy); | ||
| const employeeListUpdate = {}; | ||
| _.each(members, login => employeeListUpdate[login] = null); | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, employeeListUpdate); | ||
|
|
||
| // Make the API call to remove a login from the policy | ||
| DeprecatedAPI.Policy_Employees_Remove({ | ||
|
|
@@ -309,9 +302,10 @@ function removeMembers(members, policyID) { | |
| if (data.jsonCode === 200) { | ||
| return; | ||
| } | ||
| const policyDataWithMembersRemoved = _.clone(allPolicies[key]); | ||
| policyDataWithMembersRemoved.employeeList = [...policyDataWithMembersRemoved.employeeList, ...members]; | ||
| Onyx.set(key, policyDataWithMembersRemoved); | ||
|
|
||
| // Rollback removal on failure | ||
| _.each(members, login => employeeListUpdate[login] = {}); | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, employeeListUpdate); | ||
|
|
||
| // Show the user feedback that the removal failed | ||
| const errorMessage = data.jsonCode === 666 ? data.message : Localize.translateLocal('workspace.people.genericFailureMessage'); | ||
|
|
@@ -327,16 +321,15 @@ function removeMembers(members, policyID) { | |
| * @param {String} policyID | ||
| */ | ||
| function invite(logins, welcomeNote, policyID) { | ||
| const key = `${ONYXKEYS.COLLECTION.POLICY}${policyID}`; | ||
| const newEmployeeList = _.map(logins, login => OptionsListUtils.addSMSDomainIfPhoneNumber(login)); | ||
|
|
||
| // Make a shallow copy to preserve original data, and concat the login | ||
| const policy = _.clone(allPolicies[key]); | ||
| policy.employeeList = [...policy.employeeList, ...newEmployeeList]; | ||
| policy.alertMessage = ''; | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { | ||
| alertMessage: '', | ||
| }); | ||
|
|
||
| // Optimistically add the user to the policy | ||
| Onyx.merge(key, policy); | ||
| const newEmployeeLogins = _.map(logins, login => OptionsListUtils.addSMSDomainIfPhoneNumber(login)); | ||
| const employeeUpdate = {}; | ||
| _.each(newEmployeeLogins, login => employeeUpdate[login] = {}); | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, employeeUpdate); | ||
|
|
||
| // Make the API call to merge the login into the policy | ||
| DeprecatedAPI.Policy_Employees_Merge({ | ||
|
|
@@ -356,16 +349,15 @@ function invite(logins, welcomeNote, policyID) { | |
| } | ||
|
|
||
| // If the operation failed, undo the optimistic addition | ||
| const policyDataWithoutLogin = _.clone(allPolicies[key]); | ||
| policyDataWithoutLogin.employeeList = _.without(allPolicies[key].employeeList, ...newEmployeeList); | ||
| _.each(newEmployeeLogins, login => employeeUpdate[login] = null); | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, employeeUpdate); | ||
|
|
||
| // Show the user feedback that the addition failed | ||
| policyDataWithoutLogin.alertMessage = Localize.translateLocal('workspace.invite.genericFailureMessage'); | ||
| let alertMessage = Localize.translateLocal('workspace.invite.genericFailureMessage'); | ||
| if (data.jsonCode === 402) { | ||
| policyDataWithoutLogin.alertMessage += ` ${Localize.translateLocal('workspace.invite.pleaseEnterValidLogin')}`; | ||
| alertMessage += ` ${Localize.translateLocal('workspace.invite.pleaseEnterValidLogin')}`; | ||
| } | ||
|
|
||
| Onyx.set(key, policyDataWithoutLogin); | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {alertMessage}); | ||
| }); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ import CONST from '../../CONST'; | |
| import getComponentDisplayName from '../../libs/getComponentDisplayName'; | ||
| import * as Policy from '../../libs/actions/Policy'; | ||
| import ONYXKEYS from '../../ONYXKEYS'; | ||
| import policyMemberPropType from '../policyMemberPropType'; | ||
|
|
||
| let previousRouteName = ''; | ||
| let previousRoutePolicyID = ''; | ||
|
|
@@ -35,7 +36,7 @@ function isPreviousRouteInSameWorkspace(routeName, policyID) { | |
| } | ||
|
|
||
| const fullPolicyPropTypes = { | ||
| /** The full policy object for the current route (as opposed to the policy summary object) */ | ||
| /** The policy object for the current route */ | ||
| policy: PropTypes.shape({ | ||
| /** The ID of the policy */ | ||
| id: PropTypes.string, | ||
|
|
@@ -57,10 +58,10 @@ const fullPolicyPropTypes = { | |
|
|
||
| /** The URL for the policy avatar */ | ||
| avatarURL: PropTypes.string, | ||
|
|
||
| /** A list of emails for the employees on the policy */ | ||
| employeeList: PropTypes.arrayOf(PropTypes.string), | ||
| }), | ||
|
|
||
| /** The policy member list for the current route */ | ||
| policyMemberList: PropTypes.objectOf(policyMemberPropType), | ||
| }; | ||
|
|
||
| const fullPolicyDefaultProps = { | ||
|
|
@@ -98,13 +99,14 @@ export default function (WrappedComponent) { | |
| previousRouteName = currentRoute.name; | ||
| previousRoutePolicyID = policyID; | ||
|
|
||
| const rest = _.omit(props, ['forwardedRef', 'policy']); | ||
| const rest = _.omit(props, ['forwardedRef', 'policy', 'policyMemberList']); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Honestly not sure about this one I just followed the existing pattern. I'll see if it makes a difference |
||
| return ( | ||
| <WrappedComponent | ||
| // eslint-disable-next-line react/jsx-props-no-spreading | ||
| {...rest} | ||
| ref={props.forwardedRef} | ||
| policy={props.policy} | ||
| policyMemberList={props.policyMemberList} | ||
| /> | ||
| ); | ||
| }; | ||
|
|
@@ -121,6 +123,9 @@ export default function (WrappedComponent) { | |
| policy: { | ||
| key: props => `${ONYXKEYS.COLLECTION.POLICY}${getPolicyIDFromRoute(props.route)}`, | ||
| }, | ||
| policyMemberList: { | ||
| key: props => `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${getPolicyIDFromRoute(props.route)}`, | ||
| }, | ||
| })(withFullPolicy); | ||
| } | ||
|
|
||
|
|
||
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.
FYI, There is a regression from this change #10667
Promise.allaccepts a single param as iterable.Uh oh!
There was an error while loading. Please reload this page.
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.
FYI @arosiclair I'm planning to hire a contributor to fix this, in #10665
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.
JK it was fixed elsewhere :D