diff --git a/plugins/communications-app/BodyForm/index.jsx b/plugins/communications-app/BodyForm/index.jsx
index d5569ede..2ca2f073 100644
--- a/plugins/communications-app/BodyForm/index.jsx
+++ b/plugins/communications-app/BodyForm/index.jsx
@@ -1,26 +1,30 @@
import React from 'react';
-import PropTypes from 'prop-types';
import { Form } from '@edx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
import TextEditor from '@communications-app/src/components/bulk-email-tool/text-editor/TextEditor';
+import { useSelector, useDispatch } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context';
+import { actionCreators as formActions } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context/reducer';
import messages from './messages';
-const BodyForm = ({ formState, setFormState }) => {
+const BodyForm = () => {
const intl = useIntl();
- const { body, isFormSubmitted = false } = formState ?? {};
+ const formData = useSelector((state) => state.form);
+ const dispatch = useDispatch();
+ const { body, isFormSubmitted = false } = formData;
+
const handleChangeTextEditor = (value) => {
- setFormState({ ...formState, body: { value } });
+ dispatch(formActions.updateForm({ body: value }));
};
- const bodyValidation = body.value.length > 0;
+ const bodyValidation = body.length > 0;
return (
{intl.formatMessage(messages.bodyFormFieldLabel)}
{isFormSubmitted && !bodyValidation && (
@@ -31,14 +35,4 @@ const BodyForm = ({ formState, setFormState }) => {
);
};
-BodyForm.defaultProps = {
- formState: {},
- setFormState: () => {},
-};
-
-BodyForm.propTypes = {
- formState: PropTypes.shape({}),
- setFormState: PropTypes.func,
-};
-
export default BodyForm;
diff --git a/plugins/communications-app/RecipientsForm/index.jsx b/plugins/communications-app/RecipientsForm/index.jsx
index 5bac3daf..19e3c02c 100644
--- a/plugins/communications-app/RecipientsForm/index.jsx
+++ b/plugins/communications-app/RecipientsForm/index.jsx
@@ -2,44 +2,43 @@ import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { Form } from '@edx/paragon';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
+import { useSelector, useDispatch } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context';
+import { actionCreators as formActions } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context/reducer';
import './styles.scss';
const disableIsHasLearners = ['track', 'cohort'];
-const RecipientsForm = ({ formState, setFormState }) => {
- const {
- isFormSubmitted, emailRecipients, isEditMode, cohorts: additionalCohorts,
- } = formState ?? {};
+const RecipientsForm = (props) => {
+ const { cohorts: additionalCohorts } = props;
+ const formData = useSelector((state) => state.form);
+ const dispatch = useDispatch();
+ const { isEditMode, emailRecipients, isFormSubmitted } = formData;
- const { value: emailRecipientsInitial } = emailRecipients;
const [selectedGroups, setSelectedGroups] = useState([]);
const hasAllLearnersSelected = selectedGroups.some((group) => group === 'learners');
const handleChangeCheckBoxes = ({ target: { value, checked } }) => {
- const { value: emailRecipientsValue } = emailRecipients;
-
let newValue;
if (checked) {
- const uniqueSet = new Set([...emailRecipientsValue, value]);
+ const uniqueSet = new Set([...emailRecipients, value]);
newValue = Array.from(uniqueSet);
} else {
- newValue = emailRecipientsValue.filter((item) => item !== value);
+ newValue = emailRecipients.filter((item) => item !== value);
}
if (checked && value === 'learners') {
newValue = newValue.filter(item => !disableIsHasLearners.some(disabled => item.includes(disabled)));
}
- setFormState({ ...formState, emailRecipients: { ...emailRecipients, value: newValue } });
+ dispatch(formActions.updateForm({ emailRecipients: newValue }));
setSelectedGroups(newValue);
};
useEffect(() => {
- setSelectedGroups(emailRecipientsInitial);
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [isEditMode]);
+ setSelectedGroups(emailRecipients);
+ }, [isEditMode, emailRecipients.length, emailRecipients]);
return (
@@ -135,30 +134,28 @@ const RecipientsForm = ({ formState, setFormState }) => {
{ isFormSubmitted && selectedGroups.length === 0 && (
-
-
-
+
+
+
)}
);
};
RecipientsForm.defaultProps = {
- formState: {},
- setFormState: () => {},
+ cohorts: [],
};
RecipientsForm.propTypes = {
- formState: PropTypes.shape({}),
- setFormState: PropTypes.func,
+ cohorts: PropTypes.arrayOf(PropTypes.string),
};
export default RecipientsForm;
diff --git a/plugins/communications-app/ScheduleSection/index.jsx b/plugins/communications-app/ScheduleSection/index.jsx
index a5dcd016..3c87d3de 100644
--- a/plugins/communications-app/ScheduleSection/index.jsx
+++ b/plugins/communications-app/ScheduleSection/index.jsx
@@ -19,15 +19,19 @@ import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import ScheduleEmailForm from '@communications-app/src/components/bulk-email-tool/bulk-email-form/ScheduleEmailForm';
import useMobileResponsive from '@communications-app/src/utils/useMobileResponsive';
+import { useSelector, useDispatch } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context';
+import { actionCreators as formActions } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context/reducer';
import messages from './messages';
const formStatusToast = ['error', 'complete', 'completeSchedule'];
-const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {
+const ScheduleSection = ({ openTaskAlert }) => {
const intl = useIntl();
const isMobile = useMobileResponsive();
const [scheduleInputChanged, isScheduleInputChanged] = useState(false);
+ const formData = useSelector((state) => state.form);
+ const dispatch = useDispatch();
const {
isScheduled,
scheduleDate = '',
@@ -35,7 +39,7 @@ const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {
isEditMode,
formStatus,
isScheduledSubmitted = false,
- } = formState ?? {};
+ } = formData;
const formStatusErrors = {
error: intl.formatMessage(messages.ScheduleSectionSubmitFormError),
@@ -46,14 +50,19 @@ const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {
const handleChangeScheduled = () => {
const newSchedule = !isScheduled;
const newFormStatus = newSchedule ? 'schedule' : 'default';
- setFormState({ ...formState, formStatus: newFormStatus, isScheduled: newSchedule });
+ // setFormState({ ...formState, formStatus: newFormStatus, isScheduled: newSchedule });
+ dispatch(formActions.updateForm({ formStatus: newFormStatus, isScheduled: newSchedule }));
};
const handleScheduleDate = ({ target: { name, value } }) => {
- setFormState({ ...formState, [name]: value });
+ dispatch(formActions.updateForm({ [name]: value }));
if (!scheduleInputChanged) {
isScheduleInputChanged(true);
}
+ /* setFormState({ ...formState, [name]: value });
+ if (!scheduleInputChanged) {
+ isScheduleInputChanged(true);
+ } */
};
const scheduleFields = isScheduledSubmitted ? scheduleDate.length > 0 && scheduleTime.length > 0
@@ -62,24 +71,11 @@ const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {
const checkIsValidSchedule = isScheduled ? scheduleFields : true;
const handleResetFormValues = () => {
- const { emailRecipients, subject, body } = formState ?? {};
- const newRecipientsValue = { ...emailRecipients, value: [] };
- const newSubjectValue = { ...subject, value: '' };
- const newBodyValue = { ...body, value: '' };
-
- setFormState({
- ...formState,
- emailRecipients: newRecipientsValue,
- subject: newSubjectValue,
- body: newBodyValue,
- scheduleDate: '',
- scheduleTime: '',
- isScheduled: false,
- isEditMode: false,
- formStatus: 'default',
- isScheduleButtonClicked: false,
- isScheduledSubmitted: false,
- });
+ dispatch(formActions.resetForm());
+ };
+
+ const handleCloseToast = () => {
+ dispatch(formActions.updateForm({ formStatus: 'default' }));
};
return (
@@ -90,7 +86,7 @@ const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {
name="scheduleEmailBox"
checked={isScheduled}
onChange={handleChangeScheduled}
- disabled={formState === 'pending'}
+ disabled={formStatus === 'pending'}
>
{intl.formatMessage(messages.ScheduleSectionSubmitScheduleBox)}
@@ -124,11 +120,13 @@ const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {
{
event.preventDefault();
if (formStatus === 'schedule' && !isScheduledSubmitted) {
- setFormState({ ...formState, isScheduleButtonClicked: true });
+ dispatch(formActions.updateForm({ isScheduleButtonClicked: true }));
+ // setFormState({ ...formState, isScheduleButtonClicked: true });
}
openTaskAlert();
}}
@@ -160,9 +158,9 @@ const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {
{ setFormState({ ...formState, formStatus: 'default' }); }}
+ onClose={handleCloseToast}
>
- {formStatusErrors[formStatus] || null}
+ {formStatusErrors[formStatus] || ''}
@@ -170,14 +168,10 @@ const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {
};
ScheduleSection.defaultProps = {
- formState: {},
- setFormState: () => {},
openTaskAlert: () => {},
};
ScheduleSection.propTypes = {
- formState: PropTypes.shape({}),
- setFormState: PropTypes.func,
openTaskAlert: PropTypes.func,
};
diff --git a/plugins/communications-app/ScheduleSection/messages.js b/plugins/communications-app/ScheduleSection/messages.js
index 75baf818..e795715d 100644
--- a/plugins/communications-app/ScheduleSection/messages.js
+++ b/plugins/communications-app/ScheduleSection/messages.js
@@ -13,7 +13,7 @@ const messages = defineMessages({
},
ScheduleSectionSubmitFormError: {
id: 'schedule.section.submit.error',
- defaultMessage: 'An error occured while attempting to send the email.',
+ defaultMessage: 'An error occurred while attempting to send the email.',
description: 'An Error message located under the submit button for the email form. Visible only on a failure.',
},
ScheduleSectionSubmitFormSuccess: {
diff --git a/plugins/communications-app/SubjectForm/index.jsx b/plugins/communications-app/SubjectForm/index.jsx
index f44ad055..f7d6dc50 100644
--- a/plugins/communications-app/SubjectForm/index.jsx
+++ b/plugins/communications-app/SubjectForm/index.jsx
@@ -1,18 +1,22 @@
import React from 'react';
-import PropTypes from 'prop-types';
import { Form } from '@edx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
+import { useSelector, useDispatch } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context';
+import { actionCreators as formActions } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context/reducer';
import messages from './messages';
-const SubjectForm = ({ formState, setFormState }) => {
+const SubjectForm = () => {
const intl = useIntl();
- const { subject, isFormSubmitted } = formState ?? {};
+ const formData = useSelector((state) => state.form);
+ const dispatch = useDispatch();
+ const { subject, isFormSubmitted } = formData;
+
const handleChangeEmailSubject = ({ target: { value } }) => {
- setFormState({ ...formState, subject: { value } });
+ dispatch(formActions.updateForm({ subject: value }));
};
- const subjectValidation = subject.value.length > 0;
+ const subjectValidation = subject.length > 0;
return (
@@ -21,7 +25,7 @@ const SubjectForm = ({ formState, setFormState }) => {
name="emailSubject"
className="w-lg-50"
onChange={handleChangeEmailSubject}
- value={subject.value}
+ value={subject}
/>
{ isFormSubmitted && !subjectValidation && (
@@ -32,14 +36,4 @@ const SubjectForm = ({ formState, setFormState }) => {
);
};
-SubjectForm.defaultProps = {
- formState: {},
- setFormState: () => {},
-};
-
-SubjectForm.propTypes = {
- formState: PropTypes.shape({}),
- setFormState: PropTypes.func,
-};
-
export default SubjectForm;
diff --git a/plugins/communications-app/TaskAlertModalForm/index.jsx b/plugins/communications-app/TaskAlertModalForm/index.jsx
index 52ccb031..308dbc0e 100644
--- a/plugins/communications-app/TaskAlertModalForm/index.jsx
+++ b/plugins/communications-app/TaskAlertModalForm/index.jsx
@@ -1,48 +1,45 @@
-import React, { useCallback, useContext } from 'react';
+import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import TaskAlertModal from '@communications-app/src/components/bulk-email-tool/task-alert-modal';
import { getScheduledBulkEmailThunk } from '@communications-app/src/components/bulk-email-tool/bulk-email-task-manager/bulk-email-scheduled-emails-table/data/thunks';
import { BulkEmailContext } from '@communications-app/src/components/bulk-email-tool/bulk-email-context';
+import { useSelector, useDispatch } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context';
+import { actionCreators as formActions } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context/reducer';
import { postBulkEmailInstructorTask, patchScheduledBulkEmailInstructorTask } from './api';
import { AlertMessage, EditMessage } from './AlertTypes';
const TaskAlertModalForm = ({
- formState,
- setFormState,
+ courseId,
isTaskAlertOpen,
closeTaskAlert,
}) => {
const [, dispatch] = useContext(BulkEmailContext);
+ const formData = useSelector((state) => state.form);
+ const dispatchForm = useDispatch();
const {
isScheduled,
- emailRecipients = { value: [] },
+ emailRecipients,
scheduleDate = '',
scheduleTime = '',
isEditMode = false,
subject,
- courseId = '',
emailId = '',
schedulingId = '',
body,
isScheduleButtonClicked = false,
isFormSubmitted = false,
- } = formState ?? {};
+ } = formData;
- // eslint-disable-next-line react-hooks/exhaustive-deps
- const changeFormStatus = useCallback((status) => setFormState({ ...formState, formStatus: status }), []);
+ const changeFormStatus = (status) => dispatchForm(formActions.updateForm({ formStatus: status }));
const handlePostEmailTask = async () => {
- const emailRecipientsValue = emailRecipients.value;
- const emailSubject = subject.value;
- const emailBody = body.value;
-
const emailData = new FormData();
emailData.append('action', 'send');
- emailData.append('send_to', JSON.stringify(emailRecipientsValue));
- emailData.append('subject', emailSubject);
- emailData.append('message', emailBody);
+ emailData.append('send_to', JSON.stringify(emailRecipients));
+ emailData.append('subject', subject);
+ emailData.append('message', body);
if (isScheduled) {
emailData.append('schedule', new Date(`${scheduleDate} ${scheduleTime}`).toISOString());
@@ -61,9 +58,9 @@ const TaskAlertModalForm = ({
};
const handlePatchEmailTask = async () => {
- const emailRecipientsValue = emailRecipients.value;
- const emailSubject = subject.value;
- const emailBody = body.value;
+ const emailRecipientsValue = emailRecipients;
+ const emailSubject = subject;
+ const emailBody = body;
const emailData = {
email: {
@@ -88,8 +85,8 @@ const TaskAlertModalForm = ({
const createEmailTask = async () => {
const isScheduleValid = isScheduled ? scheduleDate.length > 0 && scheduleTime.length > 0 : true;
- const isFormValid = emailRecipients.value.length > 0 && subject.value.length > 0
- && body.value.length > 0 && isScheduleValid;
+ const isFormValid = emailRecipients.length > 0 && subject.length > 0
+ && body.length > 0 && isScheduleValid;
if (isFormValid && isEditMode) {
await handlePatchEmailTask();
@@ -99,7 +96,9 @@ const TaskAlertModalForm = ({
await handlePostEmailTask();
}
- dispatch(getScheduledBulkEmailThunk(courseId, 1));
+ if (isFormValid) {
+ dispatch(getScheduledBulkEmailThunk(courseId, 1));
+ }
};
return (
@@ -108,15 +107,15 @@ const TaskAlertModalForm = ({
alertMessage={isEditMode
? (
)
: (
)}
@@ -125,10 +124,12 @@ const TaskAlertModalForm = ({
if (event.target.name === 'continue') {
if (!isFormSubmitted) {
- setFormState({ ...formState, isFormSubmitted: true });
+ // setFormState({ ...formState, isFormSubmitted: true });
+ dispatchForm(formActions.updateForm({ isFormSubmitted: true }));
}
if (isScheduleButtonClicked) {
- setFormState({ ...formState, isScheduledSubmitted: true });
+ // setFormState({ ...formState, isScheduledSubmitted: true });
+ dispatchForm(formActions.updateForm({ isScheduledSubmitted: true }));
}
createEmailTask();
@@ -139,6 +140,7 @@ const TaskAlertModalForm = ({
};
TaskAlertModalForm.defaultProps = {
+ courseId: '',
formState: {},
setFormState: () => {},
openTaskAlert: () => {},
@@ -147,6 +149,7 @@ TaskAlertModalForm.defaultProps = {
};
TaskAlertModalForm.propTypes = {
+ courseId: PropTypes.string,
formState: PropTypes.shape({}),
setFormState: PropTypes.func,
openTaskAlert: PropTypes.func,
diff --git a/plugins/communications-app/TaskAlertModalForm/messages.js b/plugins/communications-app/TaskAlertModalForm/messages.js
index c49310c3..dfb0abc1 100644
--- a/plugins/communications-app/TaskAlertModalForm/messages.js
+++ b/plugins/communications-app/TaskAlertModalForm/messages.js
@@ -13,7 +13,7 @@ const messages = defineMessages({
},
ScheduleSectionSubmitFormError: {
id: 'schedule.section.submit.error',
- defaultMessage: 'An error occured while attempting to send the email.',
+ defaultMessage: 'An error occurred while attempting to send the email.',
description: 'An Error message located under the submit button for the email form. Visible only on a failure.',
},
ScheduleSectionSubmitFormSuccess: {