From b1cd1b1995fc9cba84a6f938942d44598a546ffa Mon Sep 17 00:00:00 2001 From: michaelroytman Date: Fri, 3 Sep 2021 11:40:06 -0400 Subject: [PATCH] fix: Fix Broken Editing of Verified Name Field This code change fixes a bug where the verified name field was not editable. This was due to the fact that the verified name was not wired up to the Redux store, so draft verified names were not stored in the Redux store. --- src/account-settings/AccountSettingsPage.jsx | 55 +++++++--------- src/account-settings/data/selectors.js | 69 +++++++++++++++++++- 2 files changed, 89 insertions(+), 35 deletions(-) diff --git a/src/account-settings/AccountSettingsPage.jsx b/src/account-settings/AccountSettingsPage.jsx index 3dcdc33..c82286c 100644 --- a/src/account-settings/AccountSettingsPage.jsx +++ b/src/account-settings/AccountSettingsPage.jsx @@ -162,8 +162,6 @@ class AccountSettingsPage extends React.Component { this.props.saveSettings(formId, values); } - isVerifiedNameEditable = (verifiedName) => ['approved', 'denied'].includes(verifiedName.status) - isEditable(fieldName) { return !this.props.staticFields.includes(fieldName); } @@ -386,23 +384,7 @@ class AccountSettingsPage extends React.Component { // Show State field only if the country is US (could include Canada later) const showState = this.props.formValues.country === COUNTRY_WITH_STATES; - const sortedVerifiedNames = this.sortVerifiedNameRecords(this.props.formValues.verifiedNameHistory.results); - const mostRecentVerifiedName = sortedVerifiedNames.length > 0 ? sortedVerifiedNames[0] : null; - const approvedVerifiedNames = sortedVerifiedNames.filter(name => name.status === 'approved'); - const approvedVerifiedName = approvedVerifiedNames.length > 0 ? approvedVerifiedNames[0] : null; - - let verifiedNameToDisplay = null; - switch (mostRecentVerifiedName && mostRecentVerifiedName.status) { - case 'approved': - case 'denied': - verifiedNameToDisplay = approvedVerifiedName; - break; - case 'submitted': - verifiedNameToDisplay = mostRecentVerifiedName; - break; - default: - verifiedNameToDisplay = null; - } + const { verifiedName } = this.props.formValues; const verifiedNameEnabled = this.props.formValues.verifiedNameHistory.verified_name_enabled; const timeZoneOptions = this.getLocalizedTimeZoneOptions( @@ -415,7 +397,7 @@ class AccountSettingsPage extends React.Component { return ( <>
- {verifiedNameEnabled && this.renderVerifiedNameMessage(mostRecentVerifiedName)} + {verifiedNameEnabled && this.renderVerifiedNameMessage(this.props.formValues.mostRecentVerifiedName)}

{this.props.intl.formatMessage(messages['account.settings.section.account.information'])} @@ -446,40 +428,40 @@ class AccountSettingsPage extends React.Component { : this.renderEmptyStaticFieldMessage() } helpText={ - verifiedNameEnabled && verifiedNameToDisplay - ? this.renderFullNameHelpText(verifiedNameToDisplay.status) + verifiedNameEnabled && verifiedName + ? this.renderFullNameHelpText(verifiedName.status) : this.props.intl.formatMessage(messages['account.settings.field.full.name.help.text']) } isEditable={ - verifiedNameEnabled && verifiedNameToDisplay - ? this.isVerifiedNameEditable(verifiedNameToDisplay) && this.isEditable('name') + verifiedNameEnabled && verifiedName + ? this.isEditable('verifiedName') && this.isEditable('name') : this.isEditable('name') } isGrayedOut={ - verifiedNameEnabled && verifiedNameToDisplay && !this.isVerifiedNameEditable(verifiedNameToDisplay) + verifiedNameEnabled && verifiedName && !this.isEditable('verifiedName') } {...editableFieldProps} /> - {verifiedNameEnabled && verifiedNameToDisplay + {verifiedNameEnabled && verifiedName && ( {this.props.intl.formatMessage(messages['account.settings.field.name.verified'])} { - this.renderVerifiedNameIcon(verifiedNameToDisplay.status) + this.renderVerifiedNameIcon(verifiedName.status) }

) } - helpText={this.renderVerifiedNameHelpText(verifiedNameToDisplay.status)} - isEditable={this.isVerifiedNameEditable(verifiedNameToDisplay) && this.isEditable('verified_name')} - isGrayedOut={!this.isVerifiedNameEditable(verifiedNameToDisplay)} - {...(this.isVerifiedNameEditable(verifiedNameToDisplay) && editableFieldProps)} + helpText={this.renderVerifiedNameHelpText(verifiedName.status)} + isEditable={this.isEditable('verifiedName')} + isGrayedOut={!this.isEditable('verifiedName')} + {...(this.isEditable('verifiedName') && editableFieldProps)} /> )} @@ -764,10 +746,17 @@ AccountSettingsPage.propTypes = { PropTypes.shape({ verified_name: PropTypes.string, status: PropTypes.string, - verified_name_enabled: PropTypes.bool, }), ), }), + verifiedName: PropTypes.shape({ + verified_name: PropTypes.string, + status: PropTypes.string, + }), + mostRecentVerifiedName: PropTypes.shape({ + verified_name: PropTypes.string, + status: PropTypes.string, + }), }).isRequired, siteLanguage: PropTypes.shape({ previousValue: PropTypes.string, diff --git a/src/account-settings/data/selectors.js b/src/account-settings/data/selectors.js index 2f717b5..b1d485b 100644 --- a/src/account-settings/data/selectors.js +++ b/src/account-settings/data/selectors.js @@ -7,9 +7,63 @@ export const accountSettingsSelector = state => ({ ...state[storeName] }); const editableFieldNameSelector = (state, props) => props.name; +const sortedVerifiedNameHistorySelector = createSelector( + accountSettingsSelector, + accountSettings => { + function sortDates(a, b) { + const aTimeSinceEpoch = new Date(a).getTime(); + const bTimeSinceEpoch = new Date(b).getTime(); + return bTimeSinceEpoch - aTimeSinceEpoch; + } + + const history = accountSettings.values.verifiedNameHistory && accountSettings.values.verifiedNameHistory.results; + + if (Array.isArray(history)) { + return history.sort(sortDates); + } + + return []; + }, +); + +const mostRecentVerifiedNameSelector = createSelector( + sortedVerifiedNameHistorySelector, + sortedHistory => (sortedHistory.length > 0 ? sortedHistory[0] : null), +); + +const mostRecentApprovedVerifiedNameValueSelector = createSelector( + sortedVerifiedNameHistorySelector, + mostRecentVerifiedNameSelector, + (sortedHistory, mostRecentVerifiedName) => { + const approvedVerifiedNames = sortedHistory.filter(name => name.status === 'approved'); + const approvedVerifiedName = approvedVerifiedNames.length > 0 ? approvedVerifiedNames[0] : null; + + let verifiedName = null; + switch (mostRecentVerifiedName && mostRecentVerifiedName.status) { + case 'approved': + case 'denied': + verifiedName = approvedVerifiedName; + break; + case 'submitted': + verifiedName = mostRecentVerifiedName; + break; + default: + verifiedName = null; + } + return verifiedName; + }, +); + const valuesSelector = createSelector( accountSettingsSelector, - accountSettings => accountSettings.values, + mostRecentVerifiedNameSelector, + mostRecentApprovedVerifiedNameValueSelector, + (accountSettings, mostRecentVerifiedNameValue, mostRecentApprovedVerifiedNameValue) => ( + { + ...accountSettings.values, + verifiedName: mostRecentApprovedVerifiedNameValue, + mostRecentVerifiedName: mostRecentVerifiedNameValue, + }), ); const draftsSelector = createSelector( @@ -69,7 +123,18 @@ export const profileDataManagerSelector = createSelector( export const staticFieldsSelector = createSelector( accountSettingsSelector, - accountSettings => (accountSettings.profileDataManager ? ['name', 'email', 'country'] : []), + mostRecentVerifiedNameSelector, + (accountSettings, verifiedName) => { + const staticFields = []; + if (accountSettings.profileDataManager) { + staticFields.push('name', 'email', 'country'); + } + if (verifiedName && ['pending', 'submitted'].includes(verifiedName.status)) { + staticFields.push('verifiedName'); + } + + return staticFields; + }, ); /**