feat: Add cancel button for editing an email (#49)
Right now, canceling edit mode is clunky. This adds a button to explicitly cancel the mode for the editor.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Button,
|
||||
Form, Icon, StatefulButton, Toast, useToggle,
|
||||
} from '@edx/paragon';
|
||||
import {
|
||||
@@ -19,11 +20,9 @@ import messages from './messages';
|
||||
import { BulkEmailContext } from '../bulk-email-context';
|
||||
import {
|
||||
addRecipient,
|
||||
clearDateTime,
|
||||
clearEditor,
|
||||
handleEditorChange,
|
||||
removeRecipient,
|
||||
setEditMode,
|
||||
} from './data/actions';
|
||||
import { editScheduledEmailThunk, postBulkEmailThunk } from './data/thunks';
|
||||
import { getScheduledBulkEmailThunk } from '../bulk-email-task-manager/bulk-email-scheduled-emails-table/data/thunks';
|
||||
@@ -103,7 +102,7 @@ function BulkEmailForm(props) {
|
||||
}
|
||||
};
|
||||
|
||||
const delayedEmailFormReset = useTimeout(resetEmailForm, 3000);
|
||||
const delayedEmailFormReset = useTimeout(resetEmailForm, 3000, editor.editMode);
|
||||
|
||||
const onFormChange = (event) => dispatch(handleEditorChange(event.target.name, event.target.value));
|
||||
|
||||
@@ -162,19 +161,15 @@ function BulkEmailForm(props) {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!!editor.scheduleDate || !!editor.scheduleTime) {
|
||||
if (editor.editMode === true) {
|
||||
toggleScheduled(true);
|
||||
}
|
||||
if (isScheduled) {
|
||||
if (editor.editMode) {
|
||||
setEmailFormStatus(FORM_SUBMIT_STATES.RESCHEDULE);
|
||||
} else {
|
||||
setEmailFormStatus(FORM_SUBMIT_STATES.SCHEDULE);
|
||||
}
|
||||
setEmailFormStatus(FORM_SUBMIT_STATES.RESCHEDULE);
|
||||
} else if (isScheduled) {
|
||||
setEmailFormStatus(FORM_SUBMIT_STATES.SCHEDULE);
|
||||
} else {
|
||||
setEmailFormStatus(FORM_SUBMIT_STATES.DEFAULT);
|
||||
}
|
||||
}, [isScheduled, editor.scheduleDate, editor.scheduleTime]);
|
||||
}, [isScheduled, editor.editMode]);
|
||||
|
||||
const AlertMessage = () => (
|
||||
<>
|
||||
@@ -267,13 +262,7 @@ function BulkEmailForm(props) {
|
||||
<Form.Checkbox
|
||||
name="scheduleEmailBox"
|
||||
checked={isScheduled}
|
||||
onChange={() => toggleScheduled((prev) => {
|
||||
if (prev) {
|
||||
dispatch(clearDateTime());
|
||||
dispatch(setEditMode(false));
|
||||
}
|
||||
return !prev;
|
||||
})}
|
||||
onChange={() => toggleScheduled((prev) => !prev)}
|
||||
disabled={emailFormStatus === FORM_SUBMIT_STATES.PENDING}
|
||||
>
|
||||
{intl.formatMessage(messages.bulkEmailFormScheduleBox)}
|
||||
@@ -290,10 +279,11 @@ function BulkEmailForm(props) {
|
||||
<div
|
||||
className={classNames('d-flex', {
|
||||
'mt-n4.5': !isScheduled && !isMobile,
|
||||
'flex-row-reverse justify-content-between align-items-end': !isMobile,
|
||||
'flex-row-reverse align-items-end': !isMobile,
|
||||
'border-top pt-2': isScheduled,
|
||||
})}
|
||||
>
|
||||
{editor.editMode && <Button className="ml-2" variant="outline-brand" onClick={() => dispatch(clearEditor())}>Cancel</Button>}
|
||||
<StatefulButton
|
||||
className="send-email-btn"
|
||||
variant="primary"
|
||||
|
||||
@@ -15,6 +15,7 @@ export function editorReducer(state, action) {
|
||||
scheduleTime: action.payload.scheduleTime || '',
|
||||
schedulingId: action.payload.schedulingId || '',
|
||||
emailId: action.payload.emailId || null,
|
||||
editMode: action.payload.editMode || false,
|
||||
};
|
||||
case 'ADD_RECIPIENT':
|
||||
return {
|
||||
@@ -36,6 +37,7 @@ export function editorReducer(state, action) {
|
||||
...state,
|
||||
scheduleDate: '',
|
||||
scheduleTime: '',
|
||||
editMode: false,
|
||||
};
|
||||
case 'CLEAR_EDITOR':
|
||||
return {
|
||||
|
||||
@@ -14,7 +14,7 @@ import { BulkEmailContext } from '../../bulk-email-context';
|
||||
import { deleteScheduledEmailThunk, getScheduledBulkEmailThunk } from './data/thunks';
|
||||
import messages from './messages';
|
||||
import ViewEmailModal from '../ViewEmailModal';
|
||||
import { copyToEditor, setEditMode } from '../../bulk-email-form/data/actions';
|
||||
import { copyToEditor } from '../../bulk-email-form/data/actions';
|
||||
|
||||
function flattenScheduledEmailsArray(emails) {
|
||||
return emails.map((email) => ({
|
||||
@@ -103,7 +103,6 @@ function BulkEmailScheduledEmailsTable({ intl }) {
|
||||
const emailRecipients = targets.replaceAll('-', ':').split(', ');
|
||||
const scheduleDate = formatDate(dateTime);
|
||||
const scheduleTime = formatTime(dateTime);
|
||||
dispatch(setEditMode(true));
|
||||
dispatch(
|
||||
copyToEditor({
|
||||
emailId,
|
||||
@@ -113,6 +112,7 @@ function BulkEmailScheduledEmailsTable({ intl }) {
|
||||
scheduleDate,
|
||||
scheduleTime,
|
||||
schedulingId,
|
||||
editMode: true,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -75,6 +75,7 @@ describe('BulkEmailScheduledEmailsTable', () => {
|
||||
|
||||
it('properly formats data for editing mode', async () => {
|
||||
const editorObj = {
|
||||
editMode: true,
|
||||
emailId: 1,
|
||||
emailBody: '<p>body</p>',
|
||||
emailSubject: 'subject',
|
||||
@@ -92,7 +93,6 @@ describe('BulkEmailScheduledEmailsTable', () => {
|
||||
render(renderBulkEmailScheduledEmailsTable());
|
||||
fireEvent.click(await screen.findByLabelText('Edit'));
|
||||
expect(actions.copyToEditor).toHaveBeenCalledWith(editorObj);
|
||||
expect(actions.setEditMode).toHaveBeenCalledWith(true);
|
||||
});
|
||||
it('removes email when delete is pressed', async () => {
|
||||
const axiosMock = new MockAdapter(getAuthenticatedHttpClient());
|
||||
|
||||
@@ -8,16 +8,17 @@ import { useRef, useEffect } from 'react';
|
||||
* and only allow one at a time.
|
||||
* @param {function} callback The function to call once the delay ends
|
||||
* @param {millisecond} delay time to delay function call
|
||||
* @param {bool} cancel cancels the callback early if true
|
||||
*/
|
||||
export default function useTimeout(callback, delay) {
|
||||
export default function useTimeout(callback, delay, cancel) {
|
||||
const timeoutRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
const timeout = timeoutRef.current;
|
||||
if (timeout) {
|
||||
if (timeout || cancel) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
}, []);
|
||||
}, [cancel]);
|
||||
|
||||
return () => {
|
||||
if (timeoutRef.current) {
|
||||
|
||||
Reference in New Issue
Block a user