diff --git a/services/web/frontend/js/features/settings/components/emails-section.tsx b/services/web/frontend/js/features/settings/components/emails-section.tsx index a8bc54b017..e58dcd213a 100644 --- a/services/web/frontend/js/features/settings/components/emails-section.tsx +++ b/services/web/frontend/js/features/settings/components/emails-section.tsx @@ -26,6 +26,20 @@ function EmailsSectionContent() { // Only show the "add email" button if the user has permission to add a secondary email const hideAddSecondaryEmail = getMeta('ol-cannot-add-secondary-email') + // Sort emails: primary first, then confirmed secondary emails, then unconfirmed secondary emails + const sortedUserEmails = [...userEmails].sort((a, b) => { + // Primary email comes first + if (a.default) return -1 + if (b.default) return 1 + + // Then sort by confirmation status + if (a.confirmedAt && !b.confirmedAt) return -1 + if (!a.confirmedAt && b.confirmedAt) return 1 + + // If both have the same status, sort by email string + return a.email.localeCompare(b.email) + }) + return ( <>

{t('emails_and_affiliations_title')}

@@ -54,7 +68,7 @@ function EmailsSectionContent() { ) : ( <> - {userEmails?.map(userEmail => ( + {sortedUserEmails.map(userEmail => (
diff --git a/services/web/frontend/js/features/settings/components/emails/row.tsx b/services/web/frontend/js/features/settings/components/emails/row.tsx index fd74281ad8..3cbb84ef9b 100644 --- a/services/web/frontend/js/features/settings/components/emails/row.tsx +++ b/services/web/frontend/js/features/settings/components/emails/row.tsx @@ -28,7 +28,7 @@ function EmailsRow({ userEmailData, primary }: EmailsRowProps) { return ( <> - + diff --git a/services/web/test/frontend/features/settings/components/emails/emails-section.test.tsx b/services/web/test/frontend/features/settings/components/emails/emails-section.test.tsx index 243d85533a..e784f6aaac 100644 --- a/services/web/test/frontend/features/settings/components/emails/emails-section.test.tsx +++ b/services/web/test/frontend/features/settings/components/emails/emails-section.test.tsx @@ -163,4 +163,56 @@ describe('', function () { screen.getByText(/sorry, something went wrong/i) screen.getByRole('button', { name: /resend confirmation code/i }) }) + + it('sorts emails with primary first, then confirmed, then unconfirmed', async function () { + const unconfirmedEmail = { ...unconfirmedUserData, email: 'b@example.com' } + const unconfirmedEmailTwo = { + ...unconfirmedUserData, + email: 'd@example.com', + } + const confirmedEmail = { + ...confirmedUserData, + email: 'a@example.com', + confirmedAt: new Date().toISOString(), + } + const confirmedEmailTwo = { + ...confirmedUserData, + email: 'e@example.com', + confirmedAt: new Date().toISOString(), + } + const primaryEmail = { + ...professionalUserData, + email: 'c@example.com', + default: true, + } + + const emails = [ + confirmedEmailTwo, + unconfirmedEmailTwo, + unconfirmedEmail, + confirmedEmail, + primaryEmail, + ] + + fetchMock.get('/user/emails?ensureAffiliation=true', emails) + render() + + await waitForElementToBeRemoved(() => screen.getByText(/loading/i)) + + const emailElements = screen.getAllByTestId(/email-row/i) + + // Primary should be first regardless of alphabetical order + expect(within(emailElements[0]).getByText('c@example.com')).to.exist + expect(within(emailElements[0]).getByText('Primary')).to.exist + + // Confirmed should be second in alphabetical order + expect(within(emailElements[1]).getByText('a@example.com')).to.exist + expect(within(emailElements[2]).getByText('e@example.com')).to.exist + + // Unconfirmed should be last in alphabetical order + expect(within(emailElements[3]).getByText('b@example.com')).to.exist + expect(within(emailElements[3]).getByText(/unconfirmed/i)).to.exist + expect(within(emailElements[4]).getByText('d@example.com')).to.exist + expect(within(emailElements[4]).getByText(/unconfirmed/i)).to.exist + }) })