From 50747195bf4163fa5d8d304e9c7f50b46e2be617 Mon Sep 17 00:00:00 2001 From: Justin Hynes Date: Tue, 11 Jan 2022 13:20:16 -0500 Subject: [PATCH] feat: Add historical email content data to bulk course email task manager [MICROBA-1621] * Add table that displays info about previously sent bulk course email messages through our tool. * Add modal to view the contents of previously sent messages. * Extract strings to a dedicated `messages.js` file to help make the `BulkEmailContentHistory.jsx` file more readable. --- .../BulkEmailContentHistory.jsx | 242 ++++++++++++++++-- .../bulk-email-task-manager/messages.js | 78 ++++++ 2 files changed, 299 insertions(+), 21 deletions(-) create mode 100644 src/components/bulk-email-tool/bulk-email-task-manager/messages.js diff --git a/src/components/bulk-email-tool/bulk-email-task-manager/BulkEmailContentHistory.jsx b/src/components/bulk-email-tool/bulk-email-task-manager/BulkEmailContentHistory.jsx index 00a2922..6a70151 100644 --- a/src/components/bulk-email-tool/bulk-email-task-manager/BulkEmailContentHistory.jsx +++ b/src/components/bulk-email-tool/bulk-email-task-manager/BulkEmailContentHistory.jsx @@ -1,41 +1,241 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; import { useParams } from 'react-router-dom'; +import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; -import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { + Alert, Button, DataTable, Modal, +} from '@edx/paragon'; +import messages from './messages'; import { getSentEmailHistory } from './api'; -export default function BulkEmailContentHistory() { +export function BulkEmailContentHistory({ intl }) { const { courseId } = useParams(); - const [emailHistoryData, setEmailHistoryData] = useState(); // eslint-disable-line no-unused-vars + const [emailHistoryData, setEmailHistoryData] = useState(); + const [errorRetrievingData, setErrorRetrievingData] = useState(false); + const [showHistoricalEmailContentTable, setShowHistoricalEmailContentTable] = useState(false); + const [isMessageModalOpen, setIsMessageModalOpen] = useState(false); + const [messageContent, setMessageContent] = useState(); - useEffect(() => { - async function fetchSentEmailHistoryData() { - const data = await getSentEmailHistory(courseId); + /** + * Async function that makes a REST API call to retrieve historical email message data sent by the bulk course email + * tool from edx-platform. + */ + async function fetchSentEmailHistoryData() { + let data = null; + try { + data = await getSentEmailHistory(courseId); + } catch (error) { + setErrorRetrievingData(true); + } + + if (data) { const { emails } = data; setEmailHistoryData(emails); + setShowHistoricalEmailContentTable(true); } - fetchSentEmailHistoryData(); - }, []); + } + + /** + * This function is responsible for setting the current `messageContent` state data. This will be the contents of a + * previously sent email message from the bulk course email tool. This also toggles a modal to be visible to display + * the message contents to the end user. + */ + const onViewMessageClick = (tableData) => { + setMessageContent(tableData); + setIsMessageModalOpen(true); + }; + + /** + * Render function for the email content history table. If an error occurs while attempting to fetch data from + * edx-platform we will render this error instead of the table. + */ + const renderError = () => ( +
+ +

+ {intl.formatMessage(messages.errorFetchingData)} +

+
+
+ ); + + /** + * Render function for the email content history table. If there is no data to display in our table we will render + * this informative message instead. + */ + const renderEmpty = () => ( +
+ +

+ {intl.formatMessage(messages.noEmailData)} +

+
+
+ ); + + /** + * Renders a modal that will display the contents of a single historical email message sent via the bulk course email + * tool to a user. + */ + const renderMessageModal = () => ( +
+ +
+

+ {intl.formatMessage(messages.modalMessageSubject)} +

+

+ {messageContent.subject} +

+
+
+

+ {intl.formatMessage(messages.modalMessageSentBy)} +

+

+ {messageContent.requester} +

+
+
+

+ {intl.formatMessage(messages.modalMessageTimeSent)} +

+

+ {messageContent.created} +

+
+
+

+ {intl.formatMessage(messages.modalMessageSentTo)} +

+

+ {messageContent.sent_to} +

+
+
+
+

+ {intl.formatMessage(messages.modalMessageBody)} +

+
+
+
+ )} + onClose={() => setIsMessageModalOpen(false)} + /> +
+ ); + + /** + * Render function for the email content history table. This function is responsible for displaying data inside of + * the table when the `Show Sent Email History` button is pressed on the page. + */ + const renderTable = () => { + // Do a little data manipulation to make it easier to display what we want in the table. Pull the email subject out + // of the email data. Transforms the `sent_to` array to a string for easier display in our table. + const tableData = emailHistoryData.map((item) => ({ + ...item, + subject: item.email.subject, + sent_to: item.sent_to.join(', '), + })); + + return ( +
+

+ {intl.formatMessage(messages.emailHistoryTableViewMessageInstructions)} +

+ ( + + ), + }, + ]} + /> +
+ ); + }; + + /** + * Today there can be three states which the renderTableData function will handle: + * 1. There was an error retrieving data from edx-platform and we can't display anything (for now). + * 2. There is no email history for this course-run and we have nothing to display to the end user. + * 3. We were able to receive historical email content and it will be presented in a table. + */ + const renderTableData = () => { + if (errorRetrievingData) { + return renderError(); + } + + if (!emailHistoryData.length) { + return renderEmpty(); + } + + return renderTable(); + }; return (
+
+ {messageContent && renderMessageModal()} +

- + {intl.formatMessage(messages.emailHistoryTableSectionButtonHeader)}

- + + {showHistoricalEmailContentTable && renderTableData()}
); } + +BulkEmailContentHistory.propTypes = { + intl: intlShape.isRequired, + row: PropTypes.shape({ + index: PropTypes.number, + }), +}; + +BulkEmailContentHistory.defaultProps = { + row: {}, +}; + +export default injectIntl(BulkEmailContentHistory); diff --git a/src/components/bulk-email-tool/bulk-email-task-manager/messages.js b/src/components/bulk-email-tool/bulk-email-task-manager/messages.js new file mode 100644 index 0000000..684bcf8 --- /dev/null +++ b/src/components/bulk-email-tool/bulk-email-task-manager/messages.js @@ -0,0 +1,78 @@ +import { defineMessages } from '@edx/frontend-platform/i18n'; + +const messages = defineMessages({ + /* BulkEmailContentHistory.jsx Messages */ + errorFetchingData: { + id: 'bulk.email.content.history.table.alert.errorFetchingData', + defaultMessage: 'An error occurred retrieving email history data for this course. Please try again later.', + }, + noEmailData: { + id: 'bulk.email.content.history.table.alert.noEmailData', + defaultMessage: 'There is no email history for this course', + }, + buttonViewMessage: { + id: 'bulk.email.content.history.table.button.viewMessage', + defaultMessage: 'View Message', + }, + modalMessageSubject: { + id: 'bulk.email.content.history.table.modal.subject', + defaultMessage: 'Subject:', + }, + modalMessageSentBy: { + id: 'bulk.email.content.history.table.modal.sentBy', + defaultMessage: 'Sent by:', + }, + modalMessageTimeSent: { + id: 'bulk.email.content.history.table.modal.timeSent', + defaultMessage: 'Time sent:', + }, + modalMessageSentTo: { + id: 'bulk.email.content.history.table.modal.sentTo', + defaultMessage: 'Sent to:', + }, + modalMessageBody: { + id: 'bulk.email.content.history.table.modal.messageBody', + defaultMessage: 'Message:', + }, + emailHistoryTableViewMessageInstructions: { + id: 'bulk.email.content.history.table.viewMessageInstructions', + defaultMessage: 'To read a sent email message, click the `View Message` button within the table.', + }, + emailHistoryTableColumnHeaderSubject: { + id: 'bulk.email.content.history.table.column.header.subject', + defaultMessage: 'Subject', + }, + emailHistoryTableColumnHeaderAuthor: { + id: 'bulk.email.content.history.table.column.header.author', + defaultMessage: 'Sent By', + }, + emailHistoryTableColumnHeaderRecipients: { + id: 'bulk.email.content.history.table.column.header.recipients', + defaultMessage: 'Sent To', + }, + emailHistoryTableColumnHeaderTimeSent: { + id: 'bulk.email.content.history.table.column.header.timeSent', + defaultMessage: 'Time Sent', + }, + emailHistoryTableColumnHeaderNumberSent: { + id: 'bulk.email.content.history.table.column.header.numberSent', + defaultMessage: 'Subject', + }, + emailHistoryTableColumnHeaderViewMessage: { + id: 'bulk.email.content.history.table.column.header.viewMessage', + defaultMessage: 'View Message', + }, + emailHistoryTableSectionButtonHeader: { + id: 'bulk.email.content.history.table.button.header', + defaultMessage: 'To see the content of previously sent emails, click this button:', + }, + emailHistoryTableSectionButton: { + id: 'bulk.email.content.history.table.button', + defaultMessage: 'Show Sent Email History', + }, + /* BulkEmailTaskManager.jsx messages */ + /* BulkEmailPendingTasks.jsx messages */ + /* BulkEmailTaskHistory.jsx messages */ +}); + +export default messages;