Skip to content

Commit 740a7a3

Browse files
Added Email list for package and seperated package email calls
1 parent 4832a01 commit 740a7a3

11 files changed

Lines changed: 136 additions & 28 deletions

File tree

app/frontend/src/components/designer/FormDesigner.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ async function schemaCreateNew() {
413413
showAssigneeInSubmissionsTable: form.value.showAssigneeInSubmissionsTable,
414414
showSubmissionConfirmation: form.value.showSubmissionConfirmation,
415415
submissionReceivedEmails: form.value.submissionReceivedEmails,
416+
submissionPackageEmails: form.value.submissionPackageEmails,
416417
reminder_enabled: false,
417418
deploymentLevel: form.value.deploymentLevel,
418419
ministry: form.value.ministry,

app/frontend/src/components/designer/settings/FormSubmissionSettings.vue

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup>
22
import { storeToRefs } from 'pinia';
3-
import { ref } from 'vue';
3+
import { computed } from 'vue';
44
import { useI18n } from 'vue-i18n';
55
66
import { useFormStore } from '~/store/form';
@@ -12,16 +12,28 @@ const { t, locale } = useI18n({ useScope: 'global' });
1212
const { form, isRTL, isFormPublished } = storeToRefs(useFormStore());
1313
1414
/* c8 ignore start */
15-
const emailArrayRules = ref([
16-
(v) =>
17-
!form.value.sendSubmissionReceivedEmail ||
15+
const makeEmailArrayRules = (enabledRefOrGetter) => [
16+
(v = []) =>
17+
!enabledRefOrGetter() ||
1818
v.length > 0 ||
1919
t('trans.formSettings.atLeastOneEmailReq'),
20-
(v) =>
21-
!form.value.sendSubmissionReceivedEmail ||
22-
v.every((item) => new RegExp(Regex.EMAIL).test(item)) ||
20+
21+
(v = []) =>
22+
!enabledRefOrGetter() ||
23+
v.every((item) => new RegExp(Regex.EMAIL).test(String(item).trim())) ||
2324
t('trans.formSettings.validEmailRequired'),
24-
]);
25+
(v) => {
26+
console.log(v, typeof v, Array.isArray(v));
27+
},
28+
];
29+
30+
const submissionReceivedEmailRules = computed(() =>
31+
makeEmailArrayRules(() => form.sendSubmissionReceivedEmail)
32+
);
33+
34+
const submissionPackageEmailRules = computed(() =>
35+
makeEmailArrayRules(() => form.enableSubmissionPackageEmail)
36+
);
2537
/* c8 ignore stop */
2638
</script>
2739

@@ -105,7 +117,7 @@ const emailArrayRules = ref([
105117
<v-combobox
106118
v-model="form.submissionReceivedEmails"
107119
:hide-no-data="false"
108-
:rules="emailArrayRules"
120+
:rules="submissionReceivedEmailRules"
109121
solid
110122
variant="outlined"
111123
hide-selected
@@ -169,6 +181,35 @@ const emailArrayRules = ref([
169181
</v-checkbox>
170182

171183
<div v-if="form.enableSubmissionPackageEmail" class="mt-4">
184+
<v-combobox
185+
v-model="form.submissionPackageEmails"
186+
:hide-no-data="false"
187+
:rules="submissionPackageEmailRules"
188+
solid
189+
variant="outlined"
190+
hide-selected
191+
clearable
192+
:hint="$t('trans.formSettings.addMoreValidEmailAddrs')"
193+
:label="$t('trans.formSettings.notificationEmailAddrs')"
194+
multiple
195+
chips
196+
closable-chips
197+
:delimiters="[' ', ',']"
198+
append-icon=""
199+
:lang="locale"
200+
>
201+
<template #no-data>
202+
<v-list-item>
203+
<v-list-item-title>
204+
<span
205+
:lang="locale"
206+
v-html="$t('trans.formSettings.pressToAddMultiEmail')"
207+
/>
208+
</v-list-item-title>
209+
</v-list-item>
210+
</template>
211+
</v-combobox>
212+
172213
<DocumentTemplate
173214
v-model:selected-template-id="form.submissionCompletionTemplateId"
174215
form-settings-mode

app/frontend/src/components/forms/manage/ManageForm.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ function enableSettingsEdit() {
105105
106106
async function updateSettings() {
107107
try {
108+
console.log('update Settings');
109+
console.log(settingsForm.value);
108110
const { valid } = await settingsForm.value.validate();
109111
if (valid) {
110112
await formStore.updateForm();

app/frontend/src/services/formService.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export default {
3636
* @note Tenant ID is automatically included via x-tenant-id header when tenant is selected
3737
*/
3838
updateForm(formId, formData) {
39+
console.log(formData);
3940
return appAxios().put(`${ApiRoutes.FORMS}/${formId}`, formData);
4041
},
4142

app/frontend/src/store/form.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ const genInitialForm = () => ({
100100
eventStreamConfig: genInitialEventStreamConfig(),
101101
enableSubmissionPackageEmail: false,
102102
submissionCompletionTemplateId: null,
103+
submissionPackageEmails: [],
103104
});
104105

105106
export const useFormStore = defineStore('form', {
@@ -465,6 +466,7 @@ export const useFormStore = defineStore('form', {
465466
},
466467
async updateForm() {
467468
try {
469+
console.log('SubPackEmails' + this.form.submissionPackageEmails);
468470
const schedule = this.form.schedule.enabled ? this.form.schedule : {};
469471
const subscribe = this.form.subscribe.enabled
470472
? this.form.subscribe
@@ -508,6 +510,7 @@ export const useFormStore = defineStore('form', {
508510
submissionCompletionTemplateId:
509511
this.form.submissionCompletionTemplateId,
510512
enableSubmissionPackageEmail: this.form.enableSubmissionPackageEmail,
513+
submissionPackageEmails: this.form.submissionPackageEmails,
511514
});
512515

513516
// update user labels with any new added labels
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @param { import("knex").Knex } knex
3+
* @returns { Promise<void> }
4+
*/
5+
exports.up = function (knex) {
6+
return knex.schema.alterTable('form', (table) => {
7+
table.specificType('submissionPackageEmails', 'text ARRAY').comment('Array of email addresses to receive submission package emails.');
8+
});
9+
};
10+
11+
/**
12+
* @param { import("knex").Knex } knex
13+
* @returns { Promise<void> }
14+
*/
15+
exports.down = function (knex) {
16+
return knex.schema.alterTable('form', (table) => {
17+
table.dropColumn('submissionPackageEmails');
18+
});
19+
};

app/src/forms/common/models/tables/form.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ class Form extends Timestamps(Model) {
171171
},
172172
showSubmissionConfirmation: { type: 'boolean' },
173173
submissionReceivedEmails: { type: ['array', 'null'], items: { type: 'string', pattern: Regex.EMAIL } },
174+
submissionPackageEmails: { type: ['array', 'null'], items: { type: 'string', pattern: Regex.EMAIL } },
174175
enableDocumentTemplates: { type: 'boolean' },
175176
enableStatusUpdates: { type: 'boolean' },
176177
enableSubmitterRevision: { type: 'boolean' },

app/src/forms/email/emailService.js

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,10 @@ const buildEmailTemplate = async (formId, formSubmissionId, emailType, referer,
8888
priority: 'normal',
8989
form,
9090
};
91-
} else if (emailType === EmailTypes.SUBMISSION_RECEIVED) {
92-
console.log('SUB REC EMAIL ' + form.enableSubmissionPackageEmail);
93-
contextToVal = form.sendSubmissionReceivedEmail ? form.submissionReceivedEmails : [];
91+
} else if (emailType === EmailTypes.SUBMISSION_PACKAGE) {
9492
if (form.enableSubmissionPackageEmail) {
95-
console.log(contextToVal);
93+
contextToVal = form.submissionPackageEmails ? form.submissionPackageEmails : [];
9694
const subPackage = await packageService.writeSubmissionPackage({ form, submission, currentUser });
97-
console.log('subPackage');
98-
console.log(subPackage.fileRecord);
9995
userTypePath = 'form/view';
10096
configData = {
10197
submissionPackagePath: `api/v1/files/${subPackage.fileRecord.id}`,
@@ -107,19 +103,21 @@ const buildEmailTemplate = async (formId, formSubmissionId, emailType, referer,
107103
priority: 'normal',
108104
form,
109105
};
110-
console.log(configData);
111106
} else {
112-
userTypePath = 'form/view';
113-
configData = {
114-
body: additionalProperties.body,
115-
bodyTemplate: 'submission-confirmation.html',
116-
title: `${form.name} Submission`,
117-
subject: `${form.name} Submission`,
118-
messageLinkText: `There is a new ${form.name} submission. Please login to review it.`,
119-
priority: 'normal',
120-
form,
121-
};
107+
contextToVal = [];
122108
}
109+
} else if (emailType === EmailTypes.SUBMISSION_RECEIVED) {
110+
contextToVal = form.sendSubmissionReceivedEmail ? form.submissionReceivedEmails : [];
111+
userTypePath = 'form/view';
112+
configData = {
113+
body: additionalProperties.body,
114+
bodyTemplate: 'submission-confirmation.html',
115+
title: `${form.name} Submission`,
116+
subject: `${form.name} Submission`,
117+
messageLinkText: `There is a new ${form.name} submission. Please login to review it.`,
118+
priority: 'normal',
119+
form,
120+
};
123121
} else if (emailType === EmailTypes.SUBMISSION_CONFIRMATION) {
124122
contextToVal = [additionalProperties.body.to];
125123
userTypePath = 'form/success';
@@ -393,6 +391,35 @@ const service = {
393391
}
394392
},
395393

394+
/**
395+
* @function submissionReceived
396+
* Completing submission of a form
397+
* @param {string} formId
398+
* @param {string} submissionId
399+
* @param {string} body
400+
* @param {string} referer
401+
* @returns The result of the email merge operation
402+
*/
403+
submissionPackage: async (formId, submissionId, body, referer, currentUser) => {
404+
try {
405+
const { configData, contexts } = await buildEmailTemplate(formId, submissionId, EmailTypes.SUBMISSION_PACKAGE, referer, currentUser, { body });
406+
if (contexts[0].to.length) {
407+
return service._sendEmailTemplate(configData, contexts);
408+
} else {
409+
return {};
410+
}
411+
} catch (e) {
412+
log.error(e.message, {
413+
function: EmailTypes.SUBMISSION_PACKAGE,
414+
formId: formId,
415+
submissionId: submissionId,
416+
body: body,
417+
referer: referer,
418+
});
419+
throw e;
420+
}
421+
},
422+
396423
/**
397424
* @function submissionReceived
398425
* Completing submission of a form

app/src/forms/email/packageService.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const JSZip = require('jszip');
2+
const config = require('config');
23

34
const cdogsService = require('../../components/cdogsService');
45
const log = require('../../components/log')(module.filename);
@@ -14,6 +15,9 @@ const fs = require('node:fs/promises');
1415
const os = require('node:os');
1516
const path = require('node:path');
1617

18+
const PERMANENT_STORAGE = config.get('files.permanent');
19+
const { StorageTypes } = require('../common/constants');
20+
1721
const streamToBuffer = async (stream) =>
1822
new Promise((resolve, reject) => {
1923
const chunks = [];
@@ -30,7 +34,6 @@ const service = {
3034
* Given the data for a submission, find uploaded files.
3135
*/
3236
findFiles: (submission) => {
33-
console.log('Parsing for file components and file ids');
3437
const files = [];
3538
const seen = new Set();
3639

@@ -233,7 +236,12 @@ const service = {
233236
fileCount: zip.fileCount,
234237
};
235238
} finally {
236-
await fs.rm(tempPath, { force: true });
239+
//comment this out when running local storage, otherwise it'll just delete the zip from the folder it's "uploaded" to
240+
if (PERMANENT_STORAGE !== StorageTypes.LOCAL_STORAGE) {
241+
await fs.rm(tempPath, { force: true });
242+
} else {
243+
console.log('Local Development, Files not deleted');
244+
}
237245
}
238246
},
239247
};

app/src/forms/form/controller.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ module.exports = {
177177
emailService.submissionReceived(req.params.formId, response.id, req.body, req.headers.referer, req.currentUser).catch((error) => {
178178
log.error('Failed to send submission received email', { error, submissionId: response.id, userId: req.currentUser.id });
179179
});
180+
emailService.submissionPackage(req.params.formId, response.id, req.body, req.headers.referer, req.currentUser).catch((error) => {
181+
log.error('Failed to send submission package email', { error, submissionId: response.id, userId: req.currentUser.id });
182+
});
180183
}
181184
// do we want to await this? could take a while, but it could fail... maybe make an explicit api call?
182185
fileService.moveSubmissionFiles(response.id, req.currentUser).catch((error) => {

0 commit comments

Comments
 (0)