From e0680636c5d69637630b5269bc24bfce26cb074a Mon Sep 17 00:00:00 2001 From: Awais Ansari <79941147+awais-ansari@users.noreply.github.com> Date: Wed, 13 Apr 2022 15:35:16 +0500 Subject: [PATCH] feat: add reported email notifications setting in legacy discussions (#281) * feat: add reported email notifications setting in legacy discussions * feat: display reported content email notification based on a flag --- .../apps/openedx/OpenedXConfigForm.jsx | 4 ++ .../apps/openedx/OpenedXConfigForm.test.jsx | 23 ++++++++++- .../ReportedContentEmailNotifications.jsx | 40 +++++++++++++++++++ .../DiscussionTopics.test.jsx | 2 + .../discussions/app-config-form/messages.js | 14 +++++++ .../discussions/data/api.js | 5 +++ .../discussions/data/redux.test.js | 6 +++ .../discussions/factories/mockApiResponses.js | 2 + 8 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/pages-and-resources/discussions/app-config-form/apps/shared/ReportedContentEmailNotifications.jsx 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: {