From 0732f3890dce1af938a834ccda678909c6b584da Mon Sep 17 00:00:00 2001
From: Kevin Foong
Date: Tue, 15 Oct 2024 18:27:52 +0800
Subject: [PATCH] feat: port approval status to mrf completion email
---
.../multirespondent-submission.service.ts | 11 ++-
src/app/services/mail/mail.service.ts | 9 +-
.../templates/MrfApprovalOutcomeEmail.tsx | 90 -------------------
.../templates/MrfWorkflowCompletionEmail.tsx | 22 ++++-
src/app/views/templates/styles.ts | 16 +++-
5 files changed, 44 insertions(+), 104 deletions(-)
delete mode 100644 src/app/views/templates/MrfApprovalOutcomeEmail.tsx
diff --git a/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts b/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts
index a172cb2c11..37ff4909a6 100644
--- a/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts
+++ b/src/app/modules/submission/multirespondent-submission/multirespondent-submission.service.ts
@@ -240,6 +240,11 @@ const sendMrfOutcomeEmails = ({
return okAsync(true)
}
+ const formQuestionAnswers = getQuestionTitleAnswerString({
+ formFields: form.form_fields,
+ responses,
+ })
+
if (isApproval) {
return MailService.sendMrfApprovalEmail({
emails: destinationEmails,
@@ -247,6 +252,7 @@ const sendMrfOutcomeEmails = ({
formTitle: form.title,
responseId: submissionId,
isRejected,
+ formQuestionAnswers,
}).orElse((error) => {
logger.error({
message: 'Failed to send approval email',
@@ -265,10 +271,7 @@ const sendMrfOutcomeEmails = ({
formId: form._id,
formTitle: form.title,
responseId: submissionId,
- formQuestionAnswers: getQuestionTitleAnswerString({
- formFields: form.form_fields,
- responses,
- }),
+ formQuestionAnswers,
}).orElse((error) => {
logger.error({
message: 'Failed to send workflow completion email',
diff --git a/src/app/services/mail/mail.service.ts b/src/app/services/mail/mail.service.ts
index d44f7ec4fa..96c2bd7a87 100644
--- a/src/app/services/mail/mail.service.ts
+++ b/src/app/services/mail/mail.service.ts
@@ -33,11 +33,9 @@ import {
getAdminEmails,
} from '../../modules/form/form.utils'
import { formatAsPercentage } from '../../utils/formatters'
-import MrfApprovalOutcomeEmail, {
- WorkflowOutcome,
-} from '../../views/templates/MrfApprovalOutcomeEmail'
import MrfWorkflowCompletionEmail, {
QuestionAnswer,
+ WorkflowOutcome,
} from '../../views/templates/MrfWorkflowCompletionEmail'
import MrfWorkflowEmail, {
WorkflowEmailData,
@@ -1138,12 +1136,14 @@ export class MailService {
formTitle,
responseId,
isRejected,
+ formQuestionAnswers,
}: {
emails: string[]
formId: string
formTitle: string
responseId: string
isRejected: boolean
+ formQuestionAnswers: QuestionAnswer[]
}) => {
const outcome = isRejected
? WorkflowOutcome.NOT_APPROVED
@@ -1152,9 +1152,10 @@ export class MailService {
formTitle,
responseId: responseId.toString(),
outcome,
+ formQuestionAnswers,
}
- const html = render(MrfApprovalOutcomeEmail(htmlData))
+ const html = render(MrfWorkflowCompletionEmail(htmlData))
const mail: MailOptions = {
to: emails,
diff --git a/src/app/views/templates/MrfApprovalOutcomeEmail.tsx b/src/app/views/templates/MrfApprovalOutcomeEmail.tsx
deleted file mode 100644
index 5ec35f4a43..0000000000
--- a/src/app/views/templates/MrfApprovalOutcomeEmail.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import {
- Body,
- Column,
- Container,
- Head,
- Heading,
- Hr,
- Html,
- Img,
- Row,
- Text,
-} from '@react-email/components'
-import { FORMSG_LOGO_URL } from '../../constants/formsg-logo'
-
-import {
- headingStyle,
- innerContainerStyle,
- outerContainerStyle,
- textStyle,
-} from './styles'
-
-export enum WorkflowOutcome {
- APPROVED = 'Approved',
- NOT_APPROVED = 'Not approved'
-}
-
-export type WorkflowOutcomeEmailData = {
- formTitle: string
- responseId: string
- outcome: WorkflowOutcome
-}
-
-export const MrfApprovalOutcomeEmail = ({
- // Defaults are provided only for testing purposes in react-email-preview.
- outcome = WorkflowOutcome.APPROVED,
- formTitle = 'Test form title',
- responseId = '64303c45828035f732088a41'
-}: WorkflowOutcomeEmailData): JSX.Element => {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- The outcome for {formTitle}.
-
-
-
-
-
- Outcome
-
-
- {outcome}
-
-
-
-
- Response ID
-
-
- {responseId}
-
-
-
-
-
-
-
-
-
-
- For more details, please contact the respondent(s) or form administrator.
-
-
-
-
-
-
- )
-}
-
-export default MrfApprovalOutcomeEmail
diff --git a/src/app/views/templates/MrfWorkflowCompletionEmail.tsx b/src/app/views/templates/MrfWorkflowCompletionEmail.tsx
index 928f3cba48..4488ab32fc 100644
--- a/src/app/views/templates/MrfWorkflowCompletionEmail.tsx
+++ b/src/app/views/templates/MrfWorkflowCompletionEmail.tsx
@@ -16,10 +16,16 @@ import {
containerStyle,
headingTextStyle,
mainStyle,
+ outcomeTextStyle,
sectionStyle,
titleTextStyle,
} from './styles'
+export enum WorkflowOutcome {
+ APPROVED = 'Approved',
+ NOT_APPROVED = 'Not approved'
+}
+
export type QuestionAnswer = {
question: string,
answer: string
@@ -29,13 +35,15 @@ export type WorkflowEmailData = {
formTitle: string
responseId: string
formQuestionAnswers: QuestionAnswer[]
+ outcome?: WorkflowOutcome | undefined
}
export const MrfWorkflowCompletionEmail = ({
// Defaults are provided only for testing purposes in react-email-preview.
formTitle = 'Test form title',
responseId = '64303c45828035f732088a41',
- formQuestionAnswers = []
+ formQuestionAnswers = [],
+ outcome
}: WorkflowEmailData): JSX.Element => {
return (
@@ -45,8 +53,18 @@ export const MrfWorkflowCompletionEmail = ({
- {formTitle} has been completed by all respondents.
+ {
+ outcome
+ ? `The outcome for ${formTitle}`
+ : `${formTitle} has been completed by all respondents.`
+ }
+ {
+ outcome ? <>
+ Outcome
+ {outcome}
+ > : null
+ }
Responses for {formTitle}
diff --git a/src/app/views/templates/styles.ts b/src/app/views/templates/styles.ts
index 3b76032f3d..38b571af88 100644
--- a/src/app/views/templates/styles.ts
+++ b/src/app/views/templates/styles.ts
@@ -60,8 +60,6 @@ export const linkStyle: NonNullable = {
const textStyles = {
'body-1': {
fontStyle: 'normal',
- fontFamily:
- "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
fontWeight: 400,
fontSize: '1rem',
lineHeight: '1.5rem',
@@ -70,13 +68,18 @@ const textStyles = {
},
h4: {
fontWeight: 500,
- fontFamily:
- "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
fontSize: '1.125rem',
lineHeight: '1.5rem',
letterSpacing: '-0.014em',
fontFeatureSettings: "'tnum' on, 'lnum' on, 'cv05' on",
},
+ h5: {
+ fontWeight: 600,
+ fontSize: '1.25rem',
+ lineHeight: '1.75rem',
+ letterSpacing: '-0.014em',
+ fontFeatureSettings: "'tnum' on, 'lnum' on, 'cv05' on",
+ },
}
export const mainStyle = {
@@ -104,6 +107,11 @@ export const headingTextStyle: NonNullable = {
fontSize: '1.5rem',
}
+export const outcomeTextStyle: NonNullable = {
+ ...textStyles['h5'],
+ color: '#000000',
+}
+
export const titleTextStyle: NonNullable = {
...textStyles['body-1'],
color: '#000000',