Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add getQuestion instance method to form field schema #103

Merged
merged 11 commits into from
Aug 11, 2020
Merged
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
"@types/node": "^14.0.13",
"@types/nodemailer": "^6.4.0",
"@types/nodemailer-direct-transport": "^1.0.31",
"@types/uid-generator": "^2.0.2",
"@types/uuid": "^8.0.0",
"@types/validator": "^13.0.0",
"@typescript-eslint/eslint-plugin": "^3.3.0",
Expand Down
18 changes: 18 additions & 0 deletions src/app/models/field/baseField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
BasicFieldType,
IFieldSchema,
IMyInfoSchema,
ITableFieldSchema,
MyInfoAttribute,
ResponseMode,
} from '../../../types'
Expand Down Expand Up @@ -125,7 +126,24 @@ const createBaseFieldSchema = (db: Mongoose) => {
return next()
})

// Instance methods
FieldSchema.methods.getQuestion = function (this: IFieldSchema) {
// Return concatenation of all column titles as question string.
if (isTableField(this)) {
const columnTitles = this.columns.map((col) => col.title)
return `${this.title} (${columnTitles.join(', ')})`
}

// Default question is the field title.
return this.title
}

return FieldSchema
}

// Typeguards
const isTableField = (field: IFieldSchema): field is ITableFieldSchema => {
return field.fieldType === BasicFieldType.Table
}

export default createBaseFieldSchema
4 changes: 4 additions & 0 deletions src/app/models/field/tableField.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isEmpty } from 'lodash'
import { Schema } from 'mongoose'

import {
Expand Down Expand Up @@ -64,6 +65,9 @@ const createTableFieldSchema = () => {
})

TableFieldSchema.pre<ITableFieldSchema>('validate', function (next) {
if (isEmpty(this.columns)) {
return next(Error('There must be at least 1 column in a Table field.'))
}
if (!this.addMoreRows && !!this.maximumRows) {
this.maximumRows = undefined
}
Expand Down
31 changes: 0 additions & 31 deletions src/app/utils/question.js

This file was deleted.

11 changes: 7 additions & 4 deletions src/app/utils/response.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const validateField = require('./field-validation')
const getQuestionFromField = require('./question')
const logicUtil = require('../../shared/util/logic')
const _ = require('lodash')
const { ConflictError } = require('./custom-errors.js')
Expand Down Expand Up @@ -71,12 +70,16 @@ const getParsedResponses = function (form, bodyResponses, modeFilter) {
// Validate each field in the form and construct parsed responses for downstream processing
const parsedResponses = responses.map((response) => {
const { _id } = response
const formField = fieldMap[_id] // In FormValidator, we have checked that all the form field ids exist, so this wont be null
// In FormValidator, we have checked that all the form field ids exist, so
// this wont be null.
const formField = fieldMap[_id]
response.isVisible = visibleFieldIds.has(_id)
validateField(form._id, formField, response)
response.question = getQuestionFromField(formField)
// Instance method of base field schema.
response.question = formField.getQuestion()
if (formField.isVerifiable) {
// This is only correct because validateField should have thrown an error if the signature was wrong.
// This is only correct because validateField should have thrown an error
// if the signature was wrong.
response.isUserVerified = true
}

Expand Down
6 changes: 5 additions & 1 deletion src/types/field/attachmentField.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export enum AttachmentSize {
OneMb = '1',
Expand All @@ -9,3 +9,7 @@ export enum AttachmentSize {
export interface IAttachmentField extends IField {
attachmentSize: AttachmentSize
}

export interface IAttachmentFieldSchema
extends IAttachmentField,
IFieldSchema {}
7 changes: 7 additions & 0 deletions src/types/field/baseField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ export interface IFieldSchema extends IField, Document {
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema

// Instance methods
/**
* Returns the string to be displayed as the asked question in form
* responses.
*/
getQuestion(): string
}

// We don't store a fieldValue in the database, but the client
Expand Down
13 changes: 2 additions & 11 deletions src/types/field/checkboxField.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export type CheckboxValidationOptions = {
customMax: number
Expand All @@ -15,10 +12,4 @@ export interface ICheckboxField extends IField {
validateByValue: boolean
}

// Manual override since mongoose types don't have generics yet.
export interface ICheckboxFieldSchema extends ICheckboxField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface ICheckboxFieldSchema extends ICheckboxField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/dateField.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export enum DateSelectedValidation {
NoPast = 'Disallow past dates',
Expand All @@ -20,10 +17,4 @@ export interface IDateField extends IField {
dateValidation: DateValidationOptions
}

// Manual override since mongoose types don't have generics yet.
export interface IDateFieldSchema extends IDateField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface IDateFieldSchema extends IDateField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/decimalField.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export type DecimalValidationOptions = {
customMax: number
Expand All @@ -13,10 +10,4 @@ export interface IDecimalField extends IField {
validateByValue: boolean
}

// Manual override since mongoose types don't have generics yet.
export interface IDecimalFieldSchema extends IDecimalField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface IDecimalFieldSchema extends IDecimalField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/dropdownField.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export interface IDropdownField extends IField {
fieldOptions: string[]
}

// Manual override since mongoose types don't have generics yet.
export interface IDropdownFieldSchema extends IDropdownField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface IDropdownFieldSchema extends IDropdownField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/emailField.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export type AutoReplyOptions = {
hasAutoReply: boolean
Expand All @@ -16,10 +13,4 @@ export interface IEmailField extends IField {
isVerifiable: boolean
}

// Manual override since mongoose types don't have generics yet.
export interface IEmailFieldSchema extends IEmailField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface IEmailFieldSchema extends IEmailField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/homeNoField.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export interface IHomenoField extends IField {
allowIntlNumbers: boolean
}

// Manual override since mongoose types don't have generics yet.
export interface IHomenoFieldSchema extends IHomenoField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface IHomenoFieldSchema extends IHomenoField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/imageField.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export interface IImageField extends IField {
url: string
Expand All @@ -10,10 +7,4 @@ export interface IImageField extends IField {
size: string
}

// Manual override since mongoose types don't have generics yet.
export interface IImageFieldSchema extends IImageField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface IImageFieldSchema extends IImageField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/longTextField.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export enum LongTextSelectedValidation {
Max = 'Maximum',
Expand All @@ -21,10 +18,4 @@ export interface ILongTextField extends IField {
ValidationOptions: LongTextValidationOptions
}

// Manual override since mongoose types don't have generics yet.
export interface ILongTextFieldSchema extends ILongTextField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface ILongTextFieldSchema extends ILongTextField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/mobileField.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export interface IMobileField extends IField {
allowIntlNumbers: boolean
isVerifiable: boolean
}

// Manual override since mongoose types don't have generics yet.
export interface IMobileFieldSchema extends IMobileField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface IMobileFieldSchema extends IMobileField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/nricField.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export interface INricField extends IField {}

// Manual override since mongoose types don't have generics yet.
export interface INricFieldSchema extends INricField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface INricFieldSchema extends INricField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/numberField.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export enum NumberSelectedValidation {
Max = 'Maximum',
Expand All @@ -21,10 +18,4 @@ export interface INumberField extends IField {
ValidationOptions: NumberValidationOptions
}

// Manual override since mongoose types don't have generics yet.
export interface INumberFieldSchema extends INumberField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface INumberFieldSchema extends INumberField, IFieldSchema {}
13 changes: 2 additions & 11 deletions src/types/field/radioField.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import { Document } from 'mongoose'

import { IFormSchema } from '../form'
import { IField } from './baseField'
import { IField, IFieldSchema } from './baseField'

export interface IRadioField extends IField {
fieldOptions: string[]
othersRadioButton: boolean
}

// Manual override since mongoose types don't have generics yet.
export interface IRadioFieldSchema extends IRadioField, Document {
/** Returns the top level document of this sub-document. */
ownerDocument(): IFormSchema
/** Returns this sub-documents parent document. */
parent(): IFormSchema
}
export interface IRadioFieldSchema extends IRadioField, IFieldSchema {}
Loading