diff --git a/src/components/learner-credit-management/members-tab/MemberStatusTableCell.jsx b/src/components/learner-credit-management/members-tab/MemberStatusTableCell.jsx index 654a96ab0f..7fc1f7ef66 100644 --- a/src/components/learner-credit-management/members-tab/MemberStatusTableCell.jsx +++ b/src/components/learner-credit-management/members-tab/MemberStatusTableCell.jsx @@ -4,7 +4,7 @@ import { Chip, Icon, Hyperlink, OverlayTrigger, Popover, } from '@openedx/paragon'; import { - CheckCircle, RemoveCircle, Timelapse, + CheckCircle, Error, RemoveCircle, Timelapse, } from '@openedx/paragon/icons'; import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; import { HELP_CENTER_GROUPS_INVITE_LINK } from '../../settings/data/constants'; @@ -63,6 +63,60 @@ const MemberStatusTableCell = ({ defaultMessage: "This member has successfully accepted the member invitation and can now browse this budget's catalog and enroll using their member permissions.", description: 'Popover body for the accepted status', }); + } else if (row.original.status === 'internal_api_error') { + icon = Error; + text = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedSystem', + defaultMessage: 'Failed: System', + description: 'Status of the member invitation', + }); + popoverHeader = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedSystemPopoverHeader', + defaultMessage: 'Failed: System', + description: 'Popover header for the system failed status', + }); + popoverBody = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedSystemPopoverBody', + defaultMessage: 'Something went wrong behind the scenes.', + description: 'Popover body for the system failed status', + }); + popoverExtra1 = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedSystemPopoverExtra1', + defaultMessage: 'Need help?', + description: 'Extra text for the system failed status', + }); + popoverExtra2 = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedSystemPopoverExtra2', + defaultMessage: 'Get help at ', + description: 'Extra text for the system failed status', + }); + } else if (row.original.status === 'email_error') { + icon = Error; + text = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedEmail', + defaultMessage: 'Failed: Bad email', + description: 'Status of the member invitation', + }); + popoverHeader = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedEmailPopoverHeader', + defaultMessage: 'Failed: Bad email', + description: 'Popover header for the failed email status', + }); + popoverBody = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedEmailPopoverBody', + defaultMessage: 'This member invitation failed because a notification to {userEmail} could not be sent.', + description: 'Popover body for the failed email status', + }, { userEmail: row.original.memberDetails.userEmail }); + popoverExtra1 = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedEmailPopoverExtra1', + defaultMessage: 'Resolution steps', + description: 'Extra text for the failed email status', + }); + popoverExtra2 = intl.formatMessage({ + id: 'learnerCreditManagement.budgetDetail.membersTab.membersTable.failedEmailPopoverExtra2', + defaultMessage: 'Remove member from budget, ensure email is correct and re-invite. Get more troubleshooting help at ', + description: 'Extra text for the failed email status', + }); } else { icon = RemoveCircle; text = intl.formatMessage({ diff --git a/src/components/learner-credit-management/members-tab/tests/MembersTab.test.jsx b/src/components/learner-credit-management/members-tab/tests/MembersTab.test.jsx index 63e8736f60..d7ce81e193 100644 --- a/src/components/learner-credit-management/members-tab/tests/MembersTab.test.jsx +++ b/src/components/learner-credit-management/members-tab/tests/MembersTab.test.jsx @@ -812,7 +812,7 @@ describe('', () => { useEnterpriseGroupMembersTableData.mockReturnValue({ isLoading: false, enterpriseGroupMembersTableData: { - itemCount: 3, + itemCount: 5, pageCount: 1, results: [{ memberDetails: { userEmail: 'dukesilver@test.com', userName: 'duke silver' }, @@ -829,6 +829,16 @@ describe('', () => { status: 'accepted', recentAction: 'Accepted: April 02, 2024', enrollmentCount: 0, + }, { + memberDetails: { userEmail: 'andydwyer@test.com', userName: 'andy dwyer' }, + status: 'internal_api_error', + recentAction: 'Errored: April 01, 2024', + enrollmentCount: 0, + }, { + memberDetails: { userEmail: 'donnameagle@test.com', userName: 'donna meagle' }, + status: 'email_error', + recentAction: 'Errored: April 01, 2024', + enrollmentCount: 0, }], }, fetchEnterpriseGroupMembersTableData: jest.fn(), @@ -852,6 +862,13 @@ describe('', () => { await waitFor(() => expect(screen.queryByText('Member removed')).toBeInTheDocument()); screen.getByText('This member has been successfully removed and can not browse this budget\'s ' + 'catalog and enroll using their member permissions.'); + + userEvent.click(screen.getByText('Failed: System')); + await waitFor(() => expect(screen.queryByText('Something went wrong behind the scenes.')).toBeInTheDocument()); + + userEvent.click(screen.getByText('Failed: Bad email')); + await waitFor(() => expect(screen.queryByText('This member invitation failed because a notification to donnameagle@test.com ' + + 'could not be sent.')).toBeInTheDocument()); }); it('download learner flow for multiple selected pages of users', async () => { // Setup