From 3deaeece2c7cf987be94b70e899766638db0ce3b Mon Sep 17 00:00:00 2001 From: Thomas Tracy Date: Wed, 13 Jul 2022 11:51:10 -0400 Subject: [PATCH] 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. --- .../bulk-email-form/BulkEmailForm.jsx | 30 +++++++------------ .../bulk-email-form/data/reducer.js | 2 ++ .../BulkEmailScheduledEmailsTable.jsx | 4 +-- .../BulkEmailScheduledEmailsTable.test.jsx | 2 +- src/utils/useTimeout.js | 7 +++-- 5 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/components/bulk-email-tool/bulk-email-form/BulkEmailForm.jsx b/src/components/bulk-email-tool/bulk-email-form/BulkEmailForm.jsx index bc11abb..c08b03d 100644 --- a/src/components/bulk-email-tool/bulk-email-form/BulkEmailForm.jsx +++ b/src/components/bulk-email-tool/bulk-email-form/BulkEmailForm.jsx @@ -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) { 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) {
+ {editor.editMode && } ({ @@ -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, }), ); }; diff --git a/src/components/bulk-email-tool/bulk-email-task-manager/bulk-email-scheduled-emails-table/test/BulkEmailScheduledEmailsTable.test.jsx b/src/components/bulk-email-tool/bulk-email-task-manager/bulk-email-scheduled-emails-table/test/BulkEmailScheduledEmailsTable.test.jsx index 7e13f1e..2847c29 100644 --- a/src/components/bulk-email-tool/bulk-email-task-manager/bulk-email-scheduled-emails-table/test/BulkEmailScheduledEmailsTable.test.jsx +++ b/src/components/bulk-email-tool/bulk-email-task-manager/bulk-email-scheduled-emails-table/test/BulkEmailScheduledEmailsTable.test.jsx @@ -75,6 +75,7 @@ describe('BulkEmailScheduledEmailsTable', () => { it('properly formats data for editing mode', async () => { const editorObj = { + editMode: true, emailId: 1, emailBody: '

body

', 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()); diff --git a/src/utils/useTimeout.js b/src/utils/useTimeout.js index 3f4b8a0..50552b0 100644 --- a/src/utils/useTimeout.js +++ b/src/utils/useTimeout.js @@ -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) {