Skip to content
This repository was archived by the owner on Dec 2, 2023. It is now read-only.

Commit b3ba5cf

Browse files
committed
add form submission hooks
1 parent 92261e7 commit b3ba5cf

File tree

4 files changed

+47
-10
lines changed

4 files changed

+47
-10
lines changed

src/dto/form/form.update.input.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Field, ID, InputType } from '@nestjs/graphql';
22
import { DesignInput } from './design.input';
33
import { FormFieldInput } from './form.field.input';
4+
import { FormHookInput } from './form.hook.input'
45
import { PageInput } from './page.input';
56
import { RespondentNotificationsInput } from './respondent.notifications.input';
67
import { SelfNotificationsInput } from './self.notifications.input';
@@ -25,6 +26,9 @@ export class FormUpdateInput {
2526
@Field(() => [FormFieldInput], { nullable: true })
2627
readonly fields: FormFieldInput[]
2728

29+
@Field(() => [FormHookInput], { nullable: true })
30+
readonly hooks: FormHookInput[]
31+
2832
@Field({ nullable: true })
2933
readonly design: DesignInput
3034

src/schema/form.schema.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { matchType } from '../config/fields';
33
import { defaultLanguage, languages } from '../config/languages';
44
import { ButtonDocument, ButtonSchema } from './button.schema';
55
import { FormFieldDocument, FormFieldSchema } from './form.field.schema';
6-
import { FormHookDocument } from './form.hook.schema'
6+
import { FormHookDocument, FormHookSchema } from './form.hook.schema'
77
import { UserDocument, UserSchemaName } from './user.schema';
88
import { VisitorDataDocument, VisitorDataSchema } from './visitor.data.schema';
99

@@ -118,6 +118,10 @@ export const FormSchema = new Schema({
118118
type: [FormFieldSchema],
119119
default: [],
120120
},
121+
hooks: {
122+
type: [FormHookSchema],
123+
default: [],
124+
},
121125
admin: {
122126
type: Schema.Types.ObjectId,
123127
ref: UserSchemaName,

src/service/form/form.update.service.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import { InjectModel } from '@nestjs/mongoose';
33
import { Model } from 'mongoose';
44
import { FormUpdateInput } from '../../dto/form/form.update.input';
55
import { FormFieldDocument, FormFieldSchemaName } from '../../schema/form.field.schema';
6+
import { FormHookDocument, FormHookSchemaName } from '../../schema/form.hook.schema'
67
import { FormDocument, FormSchemaName } from '../../schema/form.schema';
78

89
@Injectable()
910
export class FormUpdateService {
1011
constructor(
1112
@InjectModel(FormSchemaName) private readonly formModel: Model<FormDocument>,
1213
@InjectModel(FormFieldSchemaName) private readonly formFieldModel: Model<FormFieldDocument>,
14+
@InjectModel(FormHookSchemaName) private readonly formHookModel: Model<FormHookDocument>,
1315
) {
1416
}
1517

@@ -71,6 +73,27 @@ export class FormUpdateService {
7173
form.set('fields', nextFields)
7274
}
7375

76+
if (input.hooks !== undefined) {
77+
const nextHooks = input.hooks.map((nextHook) => {
78+
let hook = form.hooks && form.hooks.find(hook => hook.id.toString() === nextHook.id)
79+
80+
if (!hook) {
81+
hook = new this.formHookModel({})
82+
}
83+
84+
// ability for other fields to apply mapping
85+
hook.set('url', nextHook.url)
86+
87+
if (nextHook.format !== undefined) {
88+
hook.set('format', nextHook.format)
89+
}
90+
91+
return hook
92+
})
93+
94+
form.set('hooks', nextHooks)
95+
}
96+
7497
const extractField = (id) => {
7598
if (id && fieldMapping[id]) {
7699
return fieldMapping[id]

src/service/submission/submission.hook.service.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,32 @@ export class SubmissionHookService {
1414
}
1515

1616
public async process(submission: SubmissionDocument): Promise<void> {
17+
if (!submission.populated('form')) {
18+
submission.populate('form')
19+
await submission.execPopulate()
20+
}
21+
1722
await Promise.all(submission.form.hooks.map(async (hook) => {
1823
if (!hook.enabled) {
1924
return
2025
}
2126

2227
try {
23-
await this.httpService.post(
28+
const response = await this.httpService.post(
2429
hook.url,
2530
await this.format(submission, hook.format)
26-
)
31+
).toPromise()
32+
33+
console.log('sent', response.data)
2734
} catch (e) {
2835
this.logger.error(`failed to post to "${hook.url}: ${e.message}`)
36+
this.logger.error(e.stack)
2937
throw e
3038
}
3139
}))
3240
}
3341

3442
private async format(submission: SubmissionDocument, format?: string): Promise<any> {
35-
if (!submission.populated('form')) {
36-
submission.populate('form')
37-
await submission.execPopulate()
38-
}
39-
4043
const fields = {}
4144
submission.form.fields.forEach((field) => {
4245
fields[field.id] = field
@@ -48,12 +51,15 @@ export class SubmissionHookService {
4851
created: submission.created,
4952
lastModified: submission.lastModified,
5053
fields: submission.fields.map((submissionField) => {
51-
const formField = submission.form.fields.find(formField => formField.id.toString() === submissionField.field)
54+
const formField = submission.form.fields.find(formField => formField.id.toString() === submissionField.field) || {
55+
id: submissionField.field,
56+
slug: null
57+
}
5258

5359
return {
5460
field: formField.id,
5561
slug: formField.slug || null,
56-
value: submissionField.fieldValue
62+
...submissionField.fieldValue
5763
}
5864
})
5965
}

0 commit comments

Comments
 (0)