-
Notifications
You must be signed in to change notification settings - Fork 53
feat: same titles for sent email groups #205
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 2 commits
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 |
---|---|---|
|
@@ -2,6 +2,7 @@ import React from 'react'; | |
import PropTypes from 'prop-types'; | ||
import { Form } from '@openedx/paragon'; | ||
import { FormattedMessage } from '@edx/frontend-platform/i18n'; | ||
import { RECIPIENTS_DISPLAY_NAMES } from '../../utils'; | ||
|
||
import './bulkEmailRecepient.scss'; | ||
|
||
|
@@ -41,7 +42,7 @@ export default function BulkEmailRecipient(props) { | |
<Form.Checkbox key="myself" value="myself" className="mt-2.5 col col-lg-4 col-sm-6 col-12"> | ||
<FormattedMessage | ||
id="bulk.email.form.recipients.myself" | ||
defaultMessage="Myself" | ||
defaultMessage={RECIPIENTS_DISPLAY_NAMES.myself} | ||
|
||
description="A selectable choice from a list of potential email recipients" | ||
/> | ||
</Form.Checkbox> | ||
|
@@ -52,7 +53,7 @@ export default function BulkEmailRecipient(props) { | |
> | ||
<FormattedMessage | ||
id="bulk.email.form.recipients.staff" | ||
defaultMessage="Staff/Administrators" | ||
defaultMessage={RECIPIENTS_DISPLAY_NAMES.staff} | ||
description="A selectable choice from a list of potential email recipients" | ||
/> | ||
</Form.Checkbox> | ||
|
@@ -99,7 +100,7 @@ export default function BulkEmailRecipient(props) { | |
> | ||
<FormattedMessage | ||
id="bulk.email.form.recipients.learners" | ||
defaultMessage="All Learners" | ||
defaultMessage={RECIPIENTS_DISPLAY_NAMES.learners} | ||
description="A selectable choice from a list of potential email recipients" | ||
/> | ||
</Form.Checkbox> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ import { BulkEmailContext, BulkEmailProvider } from '../../bulk-email-context'; | |
import { formatDate } from '../../../../utils/formatDateAndTime'; | ||
import cohortFactory from '../data/__factories__/bulkEmailFormCohort.factory'; | ||
import courseModeFactory from '../data/__factories__/bulkEmailFormCourseMode.factory'; | ||
import { RECIPIENTS_DISPLAY_NAMES } from '../../utils'; | ||
|
||
jest.mock('../../text-editor/TextEditor'); | ||
|
||
|
@@ -75,8 +76,8 @@ describe('bulk-email-form', () => { | |
success: true, | ||
}); | ||
render(renderBulkEmailForm()); | ||
fireEvent.click(screen.getByRole('checkbox', { name: 'Myself' })); | ||
expect(screen.getByRole('checkbox', { name: 'Myself' })).toBeChecked(); | ||
fireEvent.click(screen.getByRole('checkbox', { name: RECIPIENTS_DISPLAY_NAMES.myself })); | ||
expect(screen.getByRole('checkbox', { name: RECIPIENTS_DISPLAY_NAMES.myself })).toBeChecked(); | ||
|
||
fireEvent.change(screen.getByRole('textbox', { name: 'Subject' }), { target: { value: 'test subject' } }); | ||
fireEvent.change(screen.getByTestId('textEditor'), { target: { value: 'test body' } }); | ||
fireEvent.click(screen.getByText('Send email')); | ||
|
@@ -90,7 +91,7 @@ describe('bulk-email-form', () => { | |
axiosMock.onPost(`${getConfig().LMS_BASE_URL}/courses/test/instructor/api/send_email`).reply(500); | ||
render(renderBulkEmailForm()); | ||
const subjectLine = screen.getByRole('textbox', { name: 'Subject' }); | ||
const recipient = screen.getByRole('checkbox', { name: 'Myself' }); | ||
const recipient = screen.getByRole('checkbox', { name: RECIPIENTS_DISPLAY_NAMES.myself }); | ||
fireEvent.click(recipient); | ||
fireEvent.change(subjectLine, { target: { value: 'test subject' } }); | ||
fireEvent.change(screen.getByTestId('textEditor'), { target: { value: 'test body' } }); | ||
|
@@ -99,9 +100,9 @@ describe('bulk-email-form', () => { | |
fireEvent.click(await screen.findByRole('button', { name: /continue/i })); | ||
expect(await screen.findByText('An error occured while attempting to send the email.')).toBeInTheDocument(); | ||
}); | ||
test('Checking "All Learners" disables each learner group', async () => { | ||
test('Checking "All Students" disables each learner group', async () => { | ||
render(renderBulkEmailForm()); | ||
fireEvent.click(screen.getByRole('checkbox', { name: 'All Learners' })); | ||
fireEvent.click(screen.getByRole('checkbox', { name: RECIPIENTS_DISPLAY_NAMES.learners })); | ||
const verifiedLearners = screen.getByRole('checkbox', { name: 'Learners in the Verified Certificate Track' }); | ||
const auditLearners = screen.getByRole('checkbox', { name: 'Learners in the Audit Track' }); | ||
const { cohorts } = cohortFactory.build(); | ||
|
@@ -130,7 +131,7 @@ describe('bulk-email-form', () => { | |
test('Adds scheduling data to POST requests when schedule is selected', async () => { | ||
const postBulkEmailInstructorTask = jest.spyOn(bulkEmailFormApi, 'postBulkEmailInstructorTask'); | ||
render(renderBulkEmailForm()); | ||
fireEvent.click(screen.getByRole('checkbox', { name: 'Myself' })); | ||
fireEvent.click(screen.getByRole('checkbox', { name: RECIPIENTS_DISPLAY_NAMES.myself })); | ||
fireEvent.change(screen.getByRole('textbox', { name: 'Subject' }), { target: { value: 'test subject' } }); | ||
fireEvent.change(screen.getByTestId('textEditor'), { target: { value: 'test body' } }); | ||
const scheduleCheckbox = screen.getByText('Schedule this email for a future date'); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ import ViewEmailModal from '../ViewEmailModal'; | |
import { copyToEditor } from '../../bulk-email-form/data/actions'; | ||
import TaskAlertModal from '../../task-alert-modal'; | ||
import { formatDate, formatTime } from '../../../../utils/formatDateAndTime'; | ||
import { getDisplayTextFromRecipient, getRecipientFromDisplayText } from '../../utils'; | ||
|
||
function flattenScheduledEmailsArray(emails) { | ||
return emails.map((email) => ({ | ||
|
@@ -28,11 +29,11 @@ function flattenScheduledEmailsArray(emails) { | |
taskDue: new Date(email.taskDue).toLocaleString(), | ||
taskDueUTC: email.taskDue, | ||
...email.courseEmail, | ||
targets: email.courseEmail.targets.join(', '), | ||
targets: email.courseEmail.targets.map(getDisplayTextFromRecipient).join(', '), | ||
})); | ||
} | ||
|
||
function BulkEmailScheduledEmailsTable({ intl }) { | ||
function BulkEmailScheduledEmailsTable({ intl, courseModes }) { | ||
const { courseId } = useParams(); | ||
const [{ scheduledEmailsTable }, dispatch] = useContext(BulkEmailContext); | ||
const [tableData, setTableData] = useState([]); | ||
|
@@ -44,8 +45,8 @@ function BulkEmailScheduledEmailsTable({ intl }) { | |
const [currentTask, setCurrentTask] = useState({}); | ||
|
||
useEffect(() => { | ||
setTableData(flattenScheduledEmailsArray(scheduledEmailsTable.results)); | ||
}, [scheduledEmailsTable.results]); | ||
setTableData(flattenScheduledEmailsArray(scheduledEmailsTable.results, courseModes)); | ||
|
||
}, [scheduledEmailsTable.results, courseModes]); | ||
|
||
const fetchTableData = useCallback((args) => { | ||
dispatch(getScheduledBulkEmailThunk(courseId, args.pageIndex + 1)); | ||
|
@@ -96,7 +97,7 @@ function BulkEmailScheduledEmailsTable({ intl }) { | |
}, | ||
} = row; | ||
const dateTime = new Date(taskDueUTC); | ||
const emailRecipients = targets.replaceAll('-', ':').split(', '); | ||
const emailRecipients = targets.replaceAll('-', ':').split(', ').map(getRecipientFromDisplayText); | ||
|
||
const scheduleDate = formatDate(dateTime); | ||
const scheduleTime = formatTime(dateTime); | ||
dispatch( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export const RECIPIENTS_DISPLAY_NAMES = { | ||
myself: 'Myself', | ||
staff: 'Staff and instructors', | ||
learners: 'All students', | ||
|
||
}; | ||
|
||
// Output: { 'Myself': 'myself', 'Staff and instructors': 'staff', 'All students': 'learners' } | ||
export const REVERSE_RECIPIENTS_DISPLAY_NAMES = Object.fromEntries( | ||
Object.entries(RECIPIENTS_DISPLAY_NAMES).map(([key, value]) => [value, key]), | ||
); | ||
|
||
export const getDisplayTextFromRecipient = (recipient) => RECIPIENTS_DISPLAY_NAMES[recipient] || recipient; | ||
|
||
export const getRecipientFromDisplayText = (recipient) => REVERSE_RECIPIENTS_DISPLAY_NAMES[recipient] || recipient; |
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.
This is not going to be internationalized, if I'm understanding this correctly.
You need to either:
getDisplayTextFromRecipient(group)
return a<FormattedMessage />
component, orgetDisplayTextFromRecipient(group)
return aMessageDescriptor
and then pass that tointl.formatMessage(...)
as seen three lines above.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 completely agree with you. Correct wrapper for localization has been added.