diff --git a/src/pages-and-resources/discussions/app-config-form/apps/openedx/OpenedXConfigForm.jsx b/src/pages-and-resources/discussions/app-config-form/apps/openedx/OpenedXConfigForm.jsx
index 5bb417908..d5ffd512f 100644
--- a/src/pages-and-resources/discussions/app-config-form/apps/openedx/OpenedXConfigForm.jsx
+++ b/src/pages-and-resources/discussions/app-config-form/apps/openedx/OpenedXConfigForm.jsx
@@ -15,6 +15,7 @@ import AppConfigFormDivider from '../shared/AppConfigFormDivider';
import BlackoutDatesField from '../shared/BlackoutDatesField';
import DiscussionTopics from '../shared/discussion-topics/DiscussionTopics';
import DivisionByGroupFields from '../shared/DivisionByGroupFields';
+import ReportedContentEmailNotifications from '../shared/ReportedContentEmailNotifications';
import InContextDiscussionFields from '../shared/InContextDiscussionFields';
import OpenedXConfigFormProvider from './OpenedXConfigFormProvider';
@@ -36,6 +37,8 @@ function OpenedXConfigForm({
unitLevelVisibility,
allowAnonymousPosts: appConfigObj?.allowAnonymousPosts || false,
allowAnonymousPostsPeers: appConfigObj?.allowAnonymousPostsPeers || false,
+ reportedContentEmailNotifications: appConfigObj?.reportedContentEmailNotifications || false,
+ enableReportedContentEmailNotifications: appConfigObj?.enableReportedContentEmailNotifications || false,
blackoutDates: appConfigObj?.blackoutDates || [],
discussionTopics: discussionTopicsModel || [],
divideByCohorts: appConfigObj?.divideByCohorts || false,
@@ -136,6 +139,7 @@ function OpenedXConfigForm({
+
diff --git a/src/pages-and-resources/discussions/app-config-form/apps/openedx/OpenedXConfigForm.test.jsx b/src/pages-and-resources/discussions/app-config-form/apps/openedx/OpenedXConfigForm.test.jsx
index fd102e619..5afae3e73 100644
--- a/src/pages-and-resources/discussions/app-config-form/apps/openedx/OpenedXConfigForm.test.jsx
+++ b/src/pages-and-resources/discussions/app-config-form/apps/openedx/OpenedXConfigForm.test.jsx
@@ -46,6 +46,8 @@ const defaultAppConfig = (divideDiscussionIds = []) => ({
unitLevelVisibility: undefined,
allowAnonymousPosts: false,
allowAnonymousPostsPeers: false,
+ reportedContentEmailNotifications: false,
+ enableReportedContentEmailNotifications: false,
allowDivisionByUnit: false,
blackoutDates: [],
});
@@ -134,7 +136,14 @@ describe('OpenedXConfigForm', () => {
});
test('default field states are correct, including removal of folded sub-fields', async () => {
- await mockStore({ ...legacyApiResponse, plugin_configuration: { divided_course_wide_discussions: [] } });
+ await mockStore({
+ ...legacyApiResponse,
+ plugin_configuration: {
+ ...legacyApiResponse.plugin_configuration,
+ reported_content_email_notifications_flag: true,
+ divided_course_wide_discussions: [],
+ },
+ });
createComponent();
const { divideDiscussionIds } = defaultAppConfig(['13f106c6-6735-4e84-b097-0456cff55960', 'course']);
@@ -154,6 +163,10 @@ describe('OpenedXConfigForm', () => {
container.querySelector('#allowAnonymousPostsPeers'),
).not.toBeInTheDocument();
+ // ReportedContentEmailNotifications
+ expect(container.querySelector('#reportedContentEmailNotifications')).toBeInTheDocument();
+ expect(container.querySelector('#reportedContentEmailNotifications')).not.toBeChecked();
+
// BlackoutDatesField
expect(queryByText(container, messages.blackoutDatesLabel.defaultMessage)).toBeInTheDocument();
});
@@ -164,6 +177,8 @@ describe('OpenedXConfigForm', () => {
plugin_configuration: {
...legacyApiResponse.plugin_configuration,
allow_anonymous: true,
+ reported_content_email_notifications: true,
+ reported_content_email_notifications_flag: true,
always_divide_inline_discussions: true,
divided_course_wide_discussions: [],
},
@@ -194,6 +209,10 @@ describe('OpenedXConfigForm', () => {
expect(
container.querySelector('#allowAnonymousPostsPeers'),
).not.toBeChecked();
+
+ // ReportedContentEmailNotifications
+ expect(container.querySelector('#reportedContentEmailNotifications')).toBeInTheDocument();
+ expect(container.querySelector('#reportedContentEmailNotifications')).toBeChecked();
});
test('folded discussion topics are in the DOM when divideByCohorts and divideCourseWideTopics are enabled',
@@ -203,6 +222,8 @@ describe('OpenedXConfigForm', () => {
plugin_configuration: {
...legacyApiResponse.plugin_configuration,
allow_anonymous: true,
+ reported_content_email_notifications: true,
+ reported_content_email_notifications_flag: true,
always_divide_inline_discussions: true,
divided_course_wide_discussions: ['13f106c6-6735-4e84-b097-0456cff55960', 'course'],
},
diff --git a/src/pages-and-resources/discussions/app-config-form/apps/shared/ReportedContentEmailNotifications.jsx b/src/pages-and-resources/discussions/app-config-form/apps/shared/ReportedContentEmailNotifications.jsx
new file mode 100644
index 000000000..4bca3a967
--- /dev/null
+++ b/src/pages-and-resources/discussions/app-config-form/apps/shared/ReportedContentEmailNotifications.jsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import { useFormikContext } from 'formik';
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import FormSwitchGroup from '../../../../../generic/FormSwitchGroup';
+import AppConfigFormDivider from './AppConfigFormDivider';
+import messages from '../../messages';
+
+function ReportedContentEmailNotifications({ intl }) {
+ const {
+ handleChange,
+ handleBlur,
+ values,
+ } = useFormikContext();
+
+ return (
+ <>
+ {values.enableReportedContentEmailNotifications && (
+
+
{intl.formatMessage(messages.reportedContentEmailNotifications)}
+
+
+
+ )}
+ >
+ );
+}
+
+ReportedContentEmailNotifications.propTypes = {
+ intl: intlShape.isRequired,
+};
+
+export default injectIntl(ReportedContentEmailNotifications);
diff --git a/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.test.jsx b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.test.jsx
index d25638e6f..9ed9b4baf 100644
--- a/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.test.jsx
+++ b/src/pages-and-resources/discussions/app-config-form/apps/shared/discussion-topics/DiscussionTopics.test.jsx
@@ -32,6 +32,8 @@ const appConfig = {
divideDiscussionIds: [],
allowAnonymousPosts: false,
allowAnonymousPostsPeers: false,
+ reportedContentEmailNotifications: false,
+ enableReportedContentEmailNotifications: false,
allowDivisionByUnit: false,
blackoutDates: [],
};
diff --git a/src/pages-and-resources/discussions/app-config-form/messages.js b/src/pages-and-resources/discussions/app-config-form/messages.js
index 20f926841..0d7f1a59e 100644
--- a/src/pages-and-resources/discussions/app-config-form/messages.js
+++ b/src/pages-and-resources/discussions/app-config-form/messages.js
@@ -185,6 +185,20 @@ const messages = defineMessages({
defaultMessage: 'Learners will be able to post anonymously to other peers but all posts will be visible to course staff.',
},
+ // Reported Email Notifications
+ reportedContentEmailNotifications: {
+ id: 'authoring.discussions.builtIn.reportedContentEmailNotifications',
+ defaultMessage: 'Notifications',
+ },
+ reportedContentEmailNotificationsLabel: {
+ id: 'authoring.discussions.builtIn.reportedContentEmailNotifications.label',
+ defaultMessage: 'Email notifications for reported content',
+ },
+ reportedContentEmailNotificationsHelp: {
+ id: 'authoring.discussions.builtIn.reportedContentEmailNotifications.help',
+ defaultMessage: 'Discussion Admins, Moderators, Community TAs and Group Community TAs (only for their own cohort) will receive an email notification when content is reported.',
+ },
+
// Discussion Topics
discussionTopics: {
id: 'authoring.discussions.discussionTopics',
diff --git a/src/pages-and-resources/discussions/data/api.js b/src/pages-and-resources/discussions/data/api.js
index f99f3fc4e..ddf80947f 100644
--- a/src/pages-and-resources/discussions/data/api.js
+++ b/src/pages-and-resources/discussions/data/api.js
@@ -61,6 +61,8 @@ function normalizePluginConfig(data) {
return {
allowAnonymousPosts: data.allow_anonymous,
allowAnonymousPostsPeers: data.allow_anonymous_to_peers,
+ reportedContentEmailNotifications: data.reported_content_email_notifications,
+ enableReportedContentEmailNotifications: data.reported_content_email_notifications_flag,
divisionScheme: data.division_scheme,
alwaysDivideInlineDiscussions: data.always_divide_inline_discussions,
blackoutDates: normalizeBlackoutDates(data.discussion_blackouts),
@@ -172,6 +174,9 @@ function denormalizeData(courseId, appId, data) {
if ('allowAnonymousPostsPeers' in data) {
pluginConfiguration.allow_anonymous_to_peers = data.allowAnonymousPostsPeers;
}
+ if ('reportedContentEmailNotifications' in data) {
+ pluginConfiguration.reported_content_email_notifications = data.reportedContentEmailNotifications;
+ }
if ('divideByCohorts' in data) {
pluginConfiguration.division_scheme = data.divideByCohorts ? DivisionSchemes.COHORT : DivisionSchemes.NONE;
pluginConfiguration.always_divide_inline_discussions = data.divideByCohorts;
diff --git a/src/pages-and-resources/discussions/data/redux.test.js b/src/pages-and-resources/discussions/data/redux.test.js
index 5d70e609b..a0b017f21 100644
--- a/src/pages-and-resources/discussions/data/redux.test.js
+++ b/src/pages-and-resources/discussions/data/redux.test.js
@@ -242,6 +242,8 @@ describe('Data layer integration tests', () => {
id: 'legacy',
allowAnonymousPosts: false,
allowAnonymousPostsPeers: false,
+ reportedContentEmailNotifications: false,
+ enableReportedContentEmailNotifications: false,
blackoutDates: [],
// TODO: Note! As of this writing, all the data below this line is NOT returned in the API
// but we add it in during normalization.
@@ -400,6 +402,7 @@ describe('Data layer integration tests', () => {
plugin_configuration: {
allow_anonymous: true,
allow_anonymous_to_peers: true,
+ reported_content_email_notifications: true,
always_divide_inline_discussions: true,
discussion_blackouts: [],
division_scheme: DivisionSchemes.COHORT,
@@ -419,6 +422,7 @@ describe('Data layer integration tests', () => {
plugin_configuration: {
allow_anonymous: true,
allow_anonymous_to_peers: true,
+ reported_content_email_notifications: true,
always_divide_inline_discussions: true,
discussion_blackouts: [],
division_scheme: DivisionSchemes.COHORT,
@@ -443,6 +447,7 @@ describe('Data layer integration tests', () => {
{
allowAnonymousPosts: true,
allowAnonymousPostsPeers: true,
+ reportedContentEmailNotifications: true,
blackoutDates: [],
// TODO: Note! As of this writing, all the data below this line is NOT returned in the API
// but we technically send it to the thunk, so here it is.
@@ -478,6 +483,7 @@ describe('Data layer integration tests', () => {
// These three fields should be updated.
allowAnonymousPosts: true,
allowAnonymousPostsPeers: true,
+ reportedContentEmailNotifications: true,
alwaysDivideInlineDiscussions: true,
blackoutDates: [],
// TODO: Note! The values we tried to save were ignored, this test reflects what currently
diff --git a/src/pages-and-resources/discussions/factories/mockApiResponses.js b/src/pages-and-resources/discussions/factories/mockApiResponses.js
index 0d165b667..0dfaf9b8f 100644
--- a/src/pages-and-resources/discussions/factories/mockApiResponses.js
+++ b/src/pages-and-resources/discussions/factories/mockApiResponses.js
@@ -90,6 +90,8 @@ export const generateLegacyApiResponse = () => ({
plugin_configuration: {
allow_anonymous: false,
allow_anonymous_to_peers: false,
+ reported_content_email_notifications: false,
+ reported_content_email_notifications_flag: false,
always_divide_inline_discussions: false,
available_division_schemes: ['enrollment_track'],
discussion_topics: {