Skip to content

Commit

Permalink
refactor: update plugins with BuildEmailFormExtensible context
Browse files Browse the repository at this point in the history
  • Loading branch information
johnvente committed Dec 22, 2023
1 parent 75f449c commit 08a3097
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 119 deletions.
26 changes: 10 additions & 16 deletions plugins/communications-app/BodyForm/index.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<Form.Group controlId="emailBody">
<Form.Label className="h3 text-primary-500">{intl.formatMessage(messages.bodyFormFieldLabel)}</Form.Label>
<TextEditor
onChange={handleChangeTextEditor}
value={body.value}
value={body}
/>
{isFormSubmitted && !bodyValidation && (
<Form.Control.Feedback className="px-3" hasIcon type="invalid">
Expand All @@ -31,14 +35,4 @@ const BodyForm = ({ formState, setFormState }) => {
);
};

BodyForm.defaultProps = {
formState: {},
setFormState: () => {},
};

BodyForm.propTypes = {
formState: PropTypes.shape({}),
setFormState: PropTypes.func,
};

export default BodyForm;
53 changes: 25 additions & 28 deletions plugins/communications-app/RecipientsForm/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<Form.Group>
Expand Down Expand Up @@ -135,30 +134,28 @@ const RecipientsForm = ({ formState, setFormState }) => {
</Form.Checkbox>
</Form.CheckboxSet>
{ isFormSubmitted && selectedGroups.length === 0 && (
<Form.Control.Feedback
className="px-3"
hasIcon
type="invalid"
>
<FormattedMessage
id="bulk.email.form.recipients.error"
defaultMessage="At least one recipient is required"
description="An Error message located under the recipients list. Visible only on failure"
/>
</Form.Control.Feedback>
<Form.Control.Feedback
className="px-3"
type="invalid"
hasIcon
>
<FormattedMessage
id="bulk.email.form.recipients.error"
defaultMessage="At least one recipient is required"
description="An Error message located under the recipients list. Visible only on failure"
/>
</Form.Control.Feedback>
)}
</Form.Group>
);
};

RecipientsForm.defaultProps = {
formState: {},
setFormState: () => {},
cohorts: [],
};

RecipientsForm.propTypes = {
formState: PropTypes.shape({}),
setFormState: PropTypes.func,
cohorts: PropTypes.arrayOf(PropTypes.string),
};

export default RecipientsForm;
54 changes: 24 additions & 30 deletions plugins/communications-app/ScheduleSection/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,27 @@ 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 = '',
scheduleTime = '',
isEditMode,
formStatus,
isScheduledSubmitted = false,
} = formState ?? {};
} = formData;

const formStatusErrors = {
error: intl.formatMessage(messages.ScheduleSectionSubmitFormError),
Expand All @@ -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
Expand All @@ -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 (
Expand All @@ -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)}
</Form.Checkbox>
Expand Down Expand Up @@ -124,11 +120,13 @@ const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {

<StatefulButton
className="send-email-btn"
data-testid="send-email-btn"
variant="primary"
onClick={(event) => {
event.preventDefault();
if (formStatus === 'schedule' && !isScheduledSubmitted) {
setFormState({ ...formState, isScheduleButtonClicked: true });
dispatch(formActions.updateForm({ isScheduleButtonClicked: true }));
// setFormState({ ...formState, isScheduleButtonClicked: true });
}
openTaskAlert();
}}
Expand Down Expand Up @@ -160,24 +158,20 @@ const ScheduleSection = ({ formState, setFormState, openTaskAlert }) => {

<Toast
show={formStatusToast.includes(formStatus)}
onClose={() => { setFormState({ ...formState, formStatus: 'default' }); }}
onClose={handleCloseToast}
>
{formStatusErrors[formStatus] || null}
{formStatusErrors[formStatus] || ''}
</Toast>
</div>
</Form.Group>
);
};

ScheduleSection.defaultProps = {
formState: {},
setFormState: () => {},
openTaskAlert: () => {},
};

ScheduleSection.propTypes = {
formState: PropTypes.shape({}),
setFormState: PropTypes.func,
openTaskAlert: PropTypes.func,
};

Expand Down
2 changes: 1 addition & 1 deletion plugins/communications-app/ScheduleSection/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
26 changes: 10 additions & 16 deletions plugins/communications-app/SubjectForm/index.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<Form.Group controlId="emailSubject" className="my-5">
Expand All @@ -21,7 +25,7 @@ const SubjectForm = ({ formState, setFormState }) => {
name="emailSubject"
className="w-lg-50"
onChange={handleChangeEmailSubject}
value={subject.value}
value={subject}
/>
{ isFormSubmitted && !subjectValidation && (
<Form.Control.Feedback className="px-3" hasIcon type="invalid">
Expand All @@ -32,14 +36,4 @@ const SubjectForm = ({ formState, setFormState }) => {
);
};

SubjectForm.defaultProps = {
formState: {},
setFormState: () => {},
};

SubjectForm.propTypes = {
formState: PropTypes.shape({}),
setFormState: PropTypes.func,
};

export default SubjectForm;
Loading

0 comments on commit 08a3097

Please sign in to comment.