@defra/forms-engine-plugin 4.17.0 → 4.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.server/server/plugins/engine/components/DatePartsField.js +2 -2
- package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
- package/.server/server/plugins/engine/components/FormComponent.d.ts +1 -0
- package/.server/server/plugins/engine/components/FormComponent.js +10 -1
- package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
- package/.server/server/plugins/engine/components/MonthYearField.js +2 -2
- package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
- package/.server/server/plugins/engine/components/UkAddressField.d.ts +1 -2
- package/.server/server/plugins/engine/components/UkAddressField.js +3 -6
- package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
- package/package.json +1 -1
- package/src/server/plugins/engine/components/DatePartsField.ts +2 -2
- package/src/server/plugins/engine/components/FormComponent.ts +14 -4
- package/src/server/plugins/engine/components/MonthYearField.ts +2 -2
- package/src/server/plugins/engine/components/UkAddressField.ts +4 -11
|
@@ -200,10 +200,10 @@ export class DatePartsField extends FormComponent {
|
|
|
200
200
|
type: 'dateMax',
|
|
201
201
|
template: messageTemplate.dateMax
|
|
202
202
|
}, {
|
|
203
|
-
type: '
|
|
203
|
+
type: 'dateEarliest',
|
|
204
204
|
template: messageTemplate.dateMin
|
|
205
205
|
}, {
|
|
206
|
-
type: '
|
|
206
|
+
type: 'dateLatest',
|
|
207
207
|
template: messageTemplate.dateMax
|
|
208
208
|
}]
|
|
209
209
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePartsField.js","names":["ComponentType","add","format","isValid","parse","startOfToday","sub","ComponentCollection","FormComponent","isFormState","isFormValue","NumberField","parseStrictDate","messageTemplate","convertToLanguageMessages","DatePartsField","constructor","def","props","name","options","isRequired","required","customValidationMessages","objectMissing","dateFormat","collection","type","title","schema","min","max","precision","optionalText","classes","parent","custom","getValidatorDate","peers","formSchema","stateSchema","getFormValueFromState","state","value","isState","undefined","getDisplayStringFromFormValue","formValue","year","month","day","getDisplayStringFromState","getContextValueFromFormValue","Date","getContextValueFromState","getViewModel","payload","errors","viewModel","fieldset","label","hasError","some","error","items","map","model","errorMessage","toString","text","trim","id","legend","isDateParts","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors","dateMin","dateMax","isNumber","component","validator","helpers","values","getStateFromValidForm","context","missing","keys","key","date","maxDaysInPast","days","limit","maxDaysInFuture","earliestDate","latestDate"],"sources":["../../../../../src/server/plugins/engine/components/DatePartsField.ts"],"sourcesContent":["import { ComponentType, type DatePartsFieldComponent } from '@defra/forms-model'\nimport { add, format, isValid, parse, startOfToday, sub } from 'date-fns'\nimport { type Context, type CustomValidator, type ObjectSchema } from 'joi'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nimport {\n type DateInputItem,\n type DatePartsState\n} from '~/src/server/plugins/engine/components/types.js'\nimport { parseStrictDate } from '~/src/server/plugins/engine/date-helper.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { convertToLanguageMessages } from '~/src/server/utils/type-utils.js'\n\nexport class DatePartsField extends FormComponent {\n declare options: DatePartsFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: DatePartsFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options } = def\n\n const isRequired = options.required !== false\n\n const customValidationMessages = convertToLanguageMessages({\n 'any.required': messageTemplate.objectMissing,\n 'number.base': messageTemplate.objectMissing,\n 'number.precision': messageTemplate.dateFormat,\n 'number.integer': messageTemplate.dateFormat,\n 'number.unsafe': messageTemplate.dateFormat,\n 'number.min': messageTemplate.dateFormat,\n 'number.max': messageTemplate.dateFormat\n })\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.NumberField,\n name: `${name}__day`,\n title: 'Day',\n schema: { min: 1, max: 31, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-2',\n customValidationMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__month`,\n title: 'Month',\n schema: { min: 1, max: 12, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-2',\n customValidationMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__year`,\n title: 'Year',\n schema: { min: 1000, max: 3000, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-4',\n customValidationMessages\n }\n }\n ],\n { ...props, parent: this },\n {\n custom: getValidatorDate(this),\n peers: [`${name}__day`, `${name}__month`, `${name}__year`]\n }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return this.isState(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(formValue: DatePartsState | undefined) {\n if (!formValue) {\n return ''\n }\n\n return format(\n `${formValue.year}-${formValue.month}-${formValue.day}`,\n 'd MMMM yyyy'\n )\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\n }\n\n getContextValueFromFormValue(value: DatePartsState | undefined) {\n if (\n !value ||\n !isValid(\n parseStrictDate(\n value,\n `${value.year}-${value.month}-${value.day}`,\n 'yyyy-MM-dd',\n new Date()\n )\n )\n ) {\n return null\n }\n\n return format(`${value.year}-${value.month}-${value.day}`, 'yyyy-MM-dd')\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const { collection, name } = this\n\n const viewModel = super.getViewModel(payload, errors)\n let { fieldset, label } = viewModel\n\n // Check for component errors only\n const hasError = errors?.some((error) => error.name === name)\n\n // Use the component collection to generate the subitems\n const items: DateInputItem[] = collection\n .getViewModel(payload, errors)\n .map(({ model }) => {\n let { label, type, value, classes, errorMessage } = model\n\n if (label) {\n label.toString = () => label.text // Date component uses string labels\n }\n\n if (hasError || errorMessage) {\n classes = `${classes} govuk-input--error`.trim()\n }\n\n // Allow any `toString()`-able value so non-numeric\n // values are shown alongside their error messages\n if (!isFormValue(value)) {\n value = undefined\n }\n\n return {\n label,\n id: model.id,\n name: model.name,\n type,\n value,\n classes\n }\n })\n\n fieldset ??= {\n legend: {\n text: label.text,\n classes: 'govuk-fieldset__legend--m'\n }\n }\n\n return {\n ...viewModel,\n fieldset,\n items\n }\n }\n\n isState(value?: FormStateValue | FormState) {\n return DatePartsField.isDateParts(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return DatePartsField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.required },\n { type: 'dateFormat', template: messageTemplate.dateFormat },\n { type: 'dateFormatDay', template: '{{#label}} must include a day' },\n {\n type: 'dateFormatMonth',\n template: '{{#label}} must include a month'\n },\n { type: 'dateFormatYear', template: '{{#label}} must include a year' }\n ],\n advancedSettingsErrors: [\n { type: 'dateMin', template: messageTemplate.dateMin },\n { type: 'dateMax', template: messageTemplate.dateMax },\n { type: 'earliestDate', template: messageTemplate.dateMin },\n { type: 'latestDate', template: messageTemplate.dateMax }\n ]\n }\n }\n\n static isDateParts(\n value?: FormStateValue | FormState\n ): value is DatePartsState {\n return (\n isFormState(value) &&\n NumberField.isNumber(value.day) &&\n NumberField.isNumber(value.month) &&\n NumberField.isNumber(value.year)\n )\n }\n}\n\nexport function getValidatorDate(component: DatePartsField) {\n const validator: CustomValidator = (payload: FormPayload, helpers) => {\n const { collection, name, options } = component\n\n const values = component.getFormValueFromState(\n component.getStateFromValidForm(payload)\n )\n\n const context: Context = {\n missing: collection.keys,\n key: name\n }\n\n if (!component.isState(values)) {\n return options.required !== false\n ? helpers.error('object.required', context)\n : payload\n }\n\n const date = parse(\n `${values.year}-${values.month}-${values.day}`,\n 'yyyy-MM-dd',\n new Date()\n )\n\n if (!isValid(date)) {\n return helpers.error('date.format', context)\n }\n\n // Minimum date from today\n const dateMin =\n options.maxDaysInPast || options.maxDaysInPast === 0\n ? sub(startOfToday(), { days: options.maxDaysInPast })\n : undefined\n\n if (dateMin && date < dateMin) {\n return helpers.error('date.min', { ...context, limit: dateMin })\n }\n\n // Maximum date from today\n const dateMax =\n options.maxDaysInFuture || options.maxDaysInFuture === 0\n ? add(startOfToday(), { days: options.maxDaysInFuture })\n : undefined\n\n if (dateMax && date > dateMax) {\n return helpers.error('date.max', { ...context, limit: dateMax })\n }\n\n // Minimum date from today\n const earliestDate = options.earliestDate\n ? new Date(options.earliestDate)\n : undefined\n\n if (earliestDate && date < earliestDate) {\n return helpers.error('date.min', { ...context, limit: earliestDate })\n }\n\n // Maximum date from today\n const latestDate = options.latestDate\n ? new Date(options.latestDate)\n : undefined\n\n if (latestDate && date > latestDate) {\n return helpers.error('date.max', { ...context, limit: latestDate })\n }\n\n return payload\n }\n\n return validator\n}\n"],"mappings":"AAAA,SAASA,aAAa,QAAsC,oBAAoB;AAChF,SAASC,GAAG,EAAEC,MAAM,EAAEC,OAAO,EAAEC,KAAK,EAAEC,YAAY,EAAEC,GAAG,QAAQ,UAAU;AAGzE,SAASC,mBAAmB;AAC5B,SACEC,aAAa,EACbC,WAAW,EACXC,WAAW;AAEb,SAASC,WAAW;AAKpB,SAASC,eAAe;AACxB,SAASC,eAAe;AASxB,SAASC,yBAAyB;AAElC,OAAO,MAAMC,cAAc,SAASP,aAAa,CAAC;EAMhDQ,WAAWA,CACTC,GAA4B,EAC5BC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEC,IAAI;MAAEC;IAAQ,CAAC,GAAGH,GAAG;IAE7B,MAAMI,UAAU,GAAGD,OAAO,CAACE,QAAQ,KAAK,KAAK;IAE7C,MAAMC,wBAAwB,GAAGT,yBAAyB,CAAC;MACzD,cAAc,EAAED,eAAe,CAACW,aAAa;MAC7C,aAAa,EAAEX,eAAe,CAACW,aAAa;MAC5C,kBAAkB,EAAEX,eAAe,CAACY,UAAU;MAC9C,gBAAgB,EAAEZ,eAAe,CAACY,UAAU;MAC5C,eAAe,EAAEZ,eAAe,CAACY,UAAU;MAC3C,YAAY,EAAEZ,eAAe,CAACY,UAAU;MACxC,YAAY,EAAEZ,eAAe,CAACY;IAChC,CAAC,CAAC;IAEF,IAAI,CAACC,UAAU,GAAG,IAAInB,mBAAmB,CACvC,CACE;MACEoB,IAAI,EAAE3B,aAAa,CAACW,WAAW;MAC/BQ,IAAI,EAAE,GAAGA,IAAI,OAAO;MACpBS,KAAK,EAAE,KAAK;MACZC,MAAM,EAAE;QAAEC,GAAG,EAAE,CAAC;QAAEC,GAAG,EAAE,EAAE;QAAEC,SAAS,EAAE;MAAE,CAAC;MACzCZ,OAAO,EAAE;QACPE,QAAQ,EAAED,UAAU;QACpBY,YAAY,EAAE,IAAI;QAClBC,OAAO,EAAE,sBAAsB;QAC/BX;MACF;IACF,CAAC,EACD;MACEI,IAAI,EAAE3B,aAAa,CAACW,WAAW;MAC/BQ,IAAI,EAAE,GAAGA,IAAI,SAAS;MACtBS,KAAK,EAAE,OAAO;MACdC,MAAM,EAAE;QAAEC,GAAG,EAAE,CAAC;QAAEC,GAAG,EAAE,EAAE;QAAEC,SAAS,EAAE;MAAE,CAAC;MACzCZ,OAAO,EAAE;QACPE,QAAQ,EAAED,UAAU;QACpBY,YAAY,EAAE,IAAI;QAClBC,OAAO,EAAE,sBAAsB;QAC/BX;MACF;IACF,CAAC,EACD;MACEI,IAAI,EAAE3B,aAAa,CAACW,WAAW;MAC/BQ,IAAI,EAAE,GAAGA,IAAI,QAAQ;MACrBS,KAAK,EAAE,MAAM;MACbC,MAAM,EAAE;QAAEC,GAAG,EAAE,IAAI;QAAEC,GAAG,EAAE,IAAI;QAAEC,SAAS,EAAE;MAAE,CAAC;MAC9CZ,OAAO,EAAE;QACPE,QAAQ,EAAED,UAAU;QACpBY,YAAY,EAAE,IAAI;QAClBC,OAAO,EAAE,sBAAsB;QAC/BX;MACF;IACF,CAAC,CACF,EACD;MAAE,GAAGL,KAAK;MAAEiB,MAAM,EAAE;IAAK,CAAC,EAC1B;MACEC,MAAM,EAAEC,gBAAgB,CAAC,IAAI,CAAC;MAC9BC,KAAK,EAAE,CAAC,GAAGnB,IAAI,OAAO,EAAE,GAAGA,IAAI,SAAS,EAAE,GAAGA,IAAI,QAAQ;IAC3D,CACF,CAAC;IAED,IAAI,CAACC,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACmB,UAAU,GAAG,IAAI,CAACb,UAAU,CAACa,UAAU;IAC5C,IAAI,CAACC,WAAW,GAAG,IAAI,CAACd,UAAU,CAACc,WAAW;EAChD;EAEAC,qBAAqBA,CAACC,KAA0B,EAAE;IAChD,MAAMC,KAAK,GAAG,KAAK,CAACF,qBAAqB,CAACC,KAAK,CAAC;IAChD,OAAO,IAAI,CAACE,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,GAAGE,SAAS;EAChD;EAEAC,6BAA6BA,CAACC,SAAqC,EAAE;IACnE,IAAI,CAACA,SAAS,EAAE;MACd,OAAO,EAAE;IACX;IAEA,OAAO7C,MAAM,CACX,GAAG6C,SAAS,CAACC,IAAI,IAAID,SAAS,CAACE,KAAK,IAAIF,SAAS,CAACG,GAAG,EAAE,EACvD,aACF,CAAC;EACH;EAEAC,yBAAyBA,CAACT,KAA0B,EAAE;IACpD,MAAMC,KAAK,GAAG,IAAI,CAACF,qBAAqB,CAACC,KAAK,CAAC;IAE/C,OAAO,IAAI,CAACI,6BAA6B,CAACH,KAAK,CAAC;EAClD;EAEAS,4BAA4BA,CAACT,KAAiC,EAAE;IAC9D,IACE,CAACA,KAAK,IACN,CAACxC,OAAO,CACNS,eAAe,CACb+B,KAAK,EACL,GAAGA,KAAK,CAACK,IAAI,IAAIL,KAAK,CAACM,KAAK,IAAIN,KAAK,CAACO,GAAG,EAAE,EAC3C,YAAY,EACZ,IAAIG,IAAI,CAAC,CACX,CACF,CAAC,EACD;MACA,OAAO,IAAI;IACb;IAEA,OAAOnD,MAAM,CAAC,GAAGyC,KAAK,CAACK,IAAI,IAAIL,KAAK,CAACM,KAAK,IAAIN,KAAK,CAACO,GAAG,EAAE,EAAE,YAAY,CAAC;EAC1E;EAEAI,wBAAwBA,CAACZ,KAA0B,EAAE;IACnD,MAAMC,KAAK,GAAG,IAAI,CAACF,qBAAqB,CAACC,KAAK,CAAC;IAE/C,OAAO,IAAI,CAACU,4BAA4B,CAACT,KAAK,CAAC;EACjD;EAEAY,YAAYA,CAACC,OAAoB,EAAEC,MAA8B,EAAE;IACjE,MAAM;MAAE/B,UAAU;MAAEP;IAAK,CAAC,GAAG,IAAI;IAEjC,MAAMuC,SAAS,GAAG,KAAK,CAACH,YAAY,CAACC,OAAO,EAAEC,MAAM,CAAC;IACrD,IAAI;MAAEE,QAAQ;MAAEC;IAAM,CAAC,GAAGF,SAAS;;IAEnC;IACA,MAAMG,QAAQ,GAAGJ,MAAM,EAAEK,IAAI,CAAEC,KAAK,IAAKA,KAAK,CAAC5C,IAAI,KAAKA,IAAI,CAAC;;IAE7D;IACA,MAAM6C,KAAsB,GAAGtC,UAAU,CACtC6B,YAAY,CAACC,OAAO,EAAEC,MAAM,CAAC,CAC7BQ,GAAG,CAAC,CAAC;MAAEC;IAAM,CAAC,KAAK;MAClB,IAAI;QAAEN,KAAK;QAAEjC,IAAI;QAAEgB,KAAK;QAAET,OAAO;QAAEiC;MAAa,CAAC,GAAGD,KAAK;MAEzD,IAAIN,KAAK,EAAE;QACTA,KAAK,CAACQ,QAAQ,GAAG,MAAMR,KAAK,CAACS,IAAI,EAAC;MACpC;MAEA,IAAIR,QAAQ,IAAIM,YAAY,EAAE;QAC5BjC,OAAO,GAAG,GAAGA,OAAO,qBAAqB,CAACoC,IAAI,CAAC,CAAC;MAClD;;MAEA;MACA;MACA,IAAI,CAAC5D,WAAW,CAACiC,KAAK,CAAC,EAAE;QACvBA,KAAK,GAAGE,SAAS;MACnB;MAEA,OAAO;QACLe,KAAK;QACLW,EAAE,EAAEL,KAAK,CAACK,EAAE;QACZpD,IAAI,EAAE+C,KAAK,CAAC/C,IAAI;QAChBQ,IAAI;QACJgB,KAAK;QACLT;MACF,CAAC;IACH,CAAC,CAAC;IAEJyB,QAAQ,KAAK;MACXa,MAAM,EAAE;QACNH,IAAI,EAAET,KAAK,CAACS,IAAI;QAChBnC,OAAO,EAAE;MACX;IACF,CAAC;IAED,OAAO;MACL,GAAGwB,SAAS;MACZC,QAAQ;MACRK;IACF,CAAC;EACH;EAEApB,OAAOA,CAACD,KAAkC,EAAE;IAC1C,OAAO5B,cAAc,CAAC0D,WAAW,CAAC9B,KAAK,CAAC;EAC1C;;EAEA;AACF;AACA;EACE+B,oBAAoBA,CAAA,EAA6B;IAC/C,OAAO3D,cAAc,CAAC2D,oBAAoB,CAAC,CAAC;EAC9C;;EAEA;AACF;AACA;EACE,OAAOA,oBAAoBA,CAAA,EAA6B;IACtD,OAAO;MACLC,UAAU,EAAE,CACV;QAAEhD,IAAI,EAAE,UAAU;QAAEiD,QAAQ,EAAE/D,eAAe,CAACS;MAAS,CAAC,EACxD;QAAEK,IAAI,EAAE,YAAY;QAAEiD,QAAQ,EAAE/D,eAAe,CAACY;MAAW,CAAC,EAC5D;QAAEE,IAAI,EAAE,eAAe;QAAEiD,QAAQ,EAAE;MAAgC,CAAC,EACpE;QACEjD,IAAI,EAAE,iBAAiB;QACvBiD,QAAQ,EAAE;MACZ,CAAC,EACD;QAAEjD,IAAI,EAAE,gBAAgB;QAAEiD,QAAQ,EAAE;MAAiC,CAAC,CACvE;MACDC,sBAAsB,EAAE,CACtB;QAAElD,IAAI,EAAE,SAAS;QAAEiD,QAAQ,EAAE/D,eAAe,CAACiE;MAAQ,CAAC,EACtD;QAAEnD,IAAI,EAAE,SAAS;QAAEiD,QAAQ,EAAE/D,eAAe,CAACkE;MAAQ,CAAC,EACtD;QAAEpD,IAAI,EAAE,cAAc;QAAEiD,QAAQ,EAAE/D,eAAe,CAACiE;MAAQ,CAAC,EAC3D;QAAEnD,IAAI,EAAE,YAAY;QAAEiD,QAAQ,EAAE/D,eAAe,CAACkE;MAAQ,CAAC;IAE7D,CAAC;EACH;EAEA,OAAON,WAAWA,CAChB9B,KAAkC,EACT;IACzB,OACElC,WAAW,CAACkC,KAAK,CAAC,IAClBhC,WAAW,CAACqE,QAAQ,CAACrC,KAAK,CAACO,GAAG,CAAC,IAC/BvC,WAAW,CAACqE,QAAQ,CAACrC,KAAK,CAACM,KAAK,CAAC,IACjCtC,WAAW,CAACqE,QAAQ,CAACrC,KAAK,CAACK,IAAI,CAAC;EAEpC;AACF;AAEA,OAAO,SAASX,gBAAgBA,CAAC4C,SAAyB,EAAE;EAC1D,MAAMC,SAA0B,GAAGA,CAAC1B,OAAoB,EAAE2B,OAAO,KAAK;IACpE,MAAM;MAAEzD,UAAU;MAAEP,IAAI;MAAEC;IAAQ,CAAC,GAAG6D,SAAS;IAE/C,MAAMG,MAAM,GAAGH,SAAS,CAACxC,qBAAqB,CAC5CwC,SAAS,CAACI,qBAAqB,CAAC7B,OAAO,CACzC,CAAC;IAED,MAAM8B,OAAgB,GAAG;MACvBC,OAAO,EAAE7D,UAAU,CAAC8D,IAAI;MACxBC,GAAG,EAAEtE;IACP,CAAC;IAED,IAAI,CAAC8D,SAAS,CAACrC,OAAO,CAACwC,MAAM,CAAC,EAAE;MAC9B,OAAOhE,OAAO,CAACE,QAAQ,KAAK,KAAK,GAC7B6D,OAAO,CAACpB,KAAK,CAAC,iBAAiB,EAAEuB,OAAO,CAAC,GACzC9B,OAAO;IACb;IAEA,MAAMkC,IAAI,GAAGtF,KAAK,CAChB,GAAGgF,MAAM,CAACpC,IAAI,IAAIoC,MAAM,CAACnC,KAAK,IAAImC,MAAM,CAAClC,GAAG,EAAE,EAC9C,YAAY,EACZ,IAAIG,IAAI,CAAC,CACX,CAAC;IAED,IAAI,CAAClD,OAAO,CAACuF,IAAI,CAAC,EAAE;MAClB,OAAOP,OAAO,CAACpB,KAAK,CAAC,aAAa,EAAEuB,OAAO,CAAC;IAC9C;;IAEA;IACA,MAAMR,OAAO,GACX1D,OAAO,CAACuE,aAAa,IAAIvE,OAAO,CAACuE,aAAa,KAAK,CAAC,GAChDrF,GAAG,CAACD,YAAY,CAAC,CAAC,EAAE;MAAEuF,IAAI,EAAExE,OAAO,CAACuE;IAAc,CAAC,CAAC,GACpD9C,SAAS;IAEf,IAAIiC,OAAO,IAAIY,IAAI,GAAGZ,OAAO,EAAE;MAC7B,OAAOK,OAAO,CAACpB,KAAK,CAAC,UAAU,EAAE;QAAE,GAAGuB,OAAO;QAAEO,KAAK,EAAEf;MAAQ,CAAC,CAAC;IAClE;;IAEA;IACA,MAAMC,OAAO,GACX3D,OAAO,CAAC0E,eAAe,IAAI1E,OAAO,CAAC0E,eAAe,KAAK,CAAC,GACpD7F,GAAG,CAACI,YAAY,CAAC,CAAC,EAAE;MAAEuF,IAAI,EAAExE,OAAO,CAAC0E;IAAgB,CAAC,CAAC,GACtDjD,SAAS;IAEf,IAAIkC,OAAO,IAAIW,IAAI,GAAGX,OAAO,EAAE;MAC7B,OAAOI,OAAO,CAACpB,KAAK,CAAC,UAAU,EAAE;QAAE,GAAGuB,OAAO;QAAEO,KAAK,EAAEd;MAAQ,CAAC,CAAC;IAClE;;IAEA;IACA,MAAMgB,YAAY,GAAG3E,OAAO,CAAC2E,YAAY,GACrC,IAAI1C,IAAI,CAACjC,OAAO,CAAC2E,YAAY,CAAC,GAC9BlD,SAAS;IAEb,IAAIkD,YAAY,IAAIL,IAAI,GAAGK,YAAY,EAAE;MACvC,OAAOZ,OAAO,CAACpB,KAAK,CAAC,UAAU,EAAE;QAAE,GAAGuB,OAAO;QAAEO,KAAK,EAAEE;MAAa,CAAC,CAAC;IACvE;;IAEA;IACA,MAAMC,UAAU,GAAG5E,OAAO,CAAC4E,UAAU,GACjC,IAAI3C,IAAI,CAACjC,OAAO,CAAC4E,UAAU,CAAC,GAC5BnD,SAAS;IAEb,IAAImD,UAAU,IAAIN,IAAI,GAAGM,UAAU,EAAE;MACnC,OAAOb,OAAO,CAACpB,KAAK,CAAC,UAAU,EAAE;QAAE,GAAGuB,OAAO;QAAEO,KAAK,EAAEG;MAAW,CAAC,CAAC;IACrE;IAEA,OAAOxC,OAAO;EAChB,CAAC;EAED,OAAO0B,SAAS;AAClB","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"DatePartsField.js","names":["ComponentType","add","format","isValid","parse","startOfToday","sub","ComponentCollection","FormComponent","isFormState","isFormValue","NumberField","parseStrictDate","messageTemplate","convertToLanguageMessages","DatePartsField","constructor","def","props","name","options","isRequired","required","customValidationMessages","objectMissing","dateFormat","collection","type","title","schema","min","max","precision","optionalText","classes","parent","custom","getValidatorDate","peers","formSchema","stateSchema","getFormValueFromState","state","value","isState","undefined","getDisplayStringFromFormValue","formValue","year","month","day","getDisplayStringFromState","getContextValueFromFormValue","Date","getContextValueFromState","getViewModel","payload","errors","viewModel","fieldset","label","hasError","some","error","items","map","model","errorMessage","toString","text","trim","id","legend","isDateParts","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors","dateMin","dateMax","isNumber","component","validator","helpers","values","getStateFromValidForm","context","missing","keys","key","date","maxDaysInPast","days","limit","maxDaysInFuture","earliestDate","latestDate"],"sources":["../../../../../src/server/plugins/engine/components/DatePartsField.ts"],"sourcesContent":["import { ComponentType, type DatePartsFieldComponent } from '@defra/forms-model'\nimport { add, format, isValid, parse, startOfToday, sub } from 'date-fns'\nimport { type Context, type CustomValidator, type ObjectSchema } from 'joi'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nimport {\n type DateInputItem,\n type DatePartsState\n} from '~/src/server/plugins/engine/components/types.js'\nimport { parseStrictDate } from '~/src/server/plugins/engine/date-helper.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { convertToLanguageMessages } from '~/src/server/utils/type-utils.js'\n\nexport class DatePartsField extends FormComponent {\n declare options: DatePartsFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: DatePartsFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options } = def\n\n const isRequired = options.required !== false\n\n const customValidationMessages = convertToLanguageMessages({\n 'any.required': messageTemplate.objectMissing,\n 'number.base': messageTemplate.objectMissing,\n 'number.precision': messageTemplate.dateFormat,\n 'number.integer': messageTemplate.dateFormat,\n 'number.unsafe': messageTemplate.dateFormat,\n 'number.min': messageTemplate.dateFormat,\n 'number.max': messageTemplate.dateFormat\n })\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.NumberField,\n name: `${name}__day`,\n title: 'Day',\n schema: { min: 1, max: 31, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-2',\n customValidationMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__month`,\n title: 'Month',\n schema: { min: 1, max: 12, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-2',\n customValidationMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__year`,\n title: 'Year',\n schema: { min: 1000, max: 3000, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-4',\n customValidationMessages\n }\n }\n ],\n { ...props, parent: this },\n {\n custom: getValidatorDate(this),\n peers: [`${name}__day`, `${name}__month`, `${name}__year`]\n }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return this.isState(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(formValue: DatePartsState | undefined) {\n if (!formValue) {\n return ''\n }\n\n return format(\n `${formValue.year}-${formValue.month}-${formValue.day}`,\n 'd MMMM yyyy'\n )\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\n }\n\n getContextValueFromFormValue(value: DatePartsState | undefined) {\n if (\n !value ||\n !isValid(\n parseStrictDate(\n value,\n `${value.year}-${value.month}-${value.day}`,\n 'yyyy-MM-dd',\n new Date()\n )\n )\n ) {\n return null\n }\n\n return format(`${value.year}-${value.month}-${value.day}`, 'yyyy-MM-dd')\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const { collection, name } = this\n\n const viewModel = super.getViewModel(payload, errors)\n let { fieldset, label } = viewModel\n\n // Check for component errors only\n const hasError = errors?.some((error) => error.name === name)\n\n // Use the component collection to generate the subitems\n const items: DateInputItem[] = collection\n .getViewModel(payload, errors)\n .map(({ model }) => {\n let { label, type, value, classes, errorMessage } = model\n\n if (label) {\n label.toString = () => label.text // Date component uses string labels\n }\n\n if (hasError || errorMessage) {\n classes = `${classes} govuk-input--error`.trim()\n }\n\n // Allow any `toString()`-able value so non-numeric\n // values are shown alongside their error messages\n if (!isFormValue(value)) {\n value = undefined\n }\n\n return {\n label,\n id: model.id,\n name: model.name,\n type,\n value,\n classes\n }\n })\n\n fieldset ??= {\n legend: {\n text: label.text,\n classes: 'govuk-fieldset__legend--m'\n }\n }\n\n return {\n ...viewModel,\n fieldset,\n items\n }\n }\n\n isState(value?: FormStateValue | FormState) {\n return DatePartsField.isDateParts(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return DatePartsField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.required },\n { type: 'dateFormat', template: messageTemplate.dateFormat },\n { type: 'dateFormatDay', template: '{{#label}} must include a day' },\n {\n type: 'dateFormatMonth',\n template: '{{#label}} must include a month'\n },\n { type: 'dateFormatYear', template: '{{#label}} must include a year' }\n ],\n advancedSettingsErrors: [\n { type: 'dateMin', template: messageTemplate.dateMin },\n { type: 'dateMax', template: messageTemplate.dateMax },\n { type: 'dateEarliest', template: messageTemplate.dateMin },\n { type: 'dateLatest', template: messageTemplate.dateMax }\n ]\n }\n }\n\n static isDateParts(\n value?: FormStateValue | FormState\n ): value is DatePartsState {\n return (\n isFormState(value) &&\n NumberField.isNumber(value.day) &&\n NumberField.isNumber(value.month) &&\n NumberField.isNumber(value.year)\n )\n }\n}\n\nexport function getValidatorDate(component: DatePartsField) {\n const validator: CustomValidator = (payload: FormPayload, helpers) => {\n const { collection, name, options } = component\n\n const values = component.getFormValueFromState(\n component.getStateFromValidForm(payload)\n )\n\n const context: Context = {\n missing: collection.keys,\n key: name\n }\n\n if (!component.isState(values)) {\n return options.required !== false\n ? helpers.error('object.required', context)\n : payload\n }\n\n const date = parse(\n `${values.year}-${values.month}-${values.day}`,\n 'yyyy-MM-dd',\n new Date()\n )\n\n if (!isValid(date)) {\n return helpers.error('date.format', context)\n }\n\n // Minimum date from today\n const dateMin =\n options.maxDaysInPast || options.maxDaysInPast === 0\n ? sub(startOfToday(), { days: options.maxDaysInPast })\n : undefined\n\n if (dateMin && date < dateMin) {\n return helpers.error('date.min', { ...context, limit: dateMin })\n }\n\n // Maximum date from today\n const dateMax =\n options.maxDaysInFuture || options.maxDaysInFuture === 0\n ? add(startOfToday(), { days: options.maxDaysInFuture })\n : undefined\n\n if (dateMax && date > dateMax) {\n return helpers.error('date.max', { ...context, limit: dateMax })\n }\n\n // Minimum date from today\n const earliestDate = options.earliestDate\n ? new Date(options.earliestDate)\n : undefined\n\n if (earliestDate && date < earliestDate) {\n return helpers.error('date.min', { ...context, limit: earliestDate })\n }\n\n // Maximum date from today\n const latestDate = options.latestDate\n ? new Date(options.latestDate)\n : undefined\n\n if (latestDate && date > latestDate) {\n return helpers.error('date.max', { ...context, limit: latestDate })\n }\n\n return payload\n }\n\n return validator\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -9,6 +9,7 @@ export declare class FormComponent extends ComponentBase {
|
|
|
9
9
|
isFormComponent: boolean;
|
|
10
10
|
isAppendageStateSingleObject: boolean;
|
|
11
11
|
constructor(def: FormComponentsDef, props: ConstructorParameters<typeof ComponentBase>[1]);
|
|
12
|
+
getLabel(def: FormComponentsDef): string;
|
|
12
13
|
get keys(): string[];
|
|
13
14
|
getFormDataFromState(state: FormSubmissionState): FormPayload;
|
|
14
15
|
getFormValueFromState(state: FormSubmissionState): FormValue | FormPayload;
|
|
@@ -14,7 +14,16 @@ export class FormComponent extends ComponentBase {
|
|
|
14
14
|
} = def;
|
|
15
15
|
this.type = type;
|
|
16
16
|
this.hint = hint;
|
|
17
|
-
this.label =
|
|
17
|
+
this.label = this.getLabel(def);
|
|
18
|
+
}
|
|
19
|
+
getLabel(def) {
|
|
20
|
+
if ('errorDescription' in def && def.errorDescription) {
|
|
21
|
+
return def.errorDescription;
|
|
22
|
+
}
|
|
23
|
+
if ('shortDescription' in def && def.shortDescription) {
|
|
24
|
+
return def.shortDescription;
|
|
25
|
+
}
|
|
26
|
+
return def.title;
|
|
18
27
|
}
|
|
19
28
|
get keys() {
|
|
20
29
|
const {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormComponent.js","names":["ComponentBase","optionalText","FormComponent","type","hint","label","isFormComponent","isAppendageStateSingleObject","constructor","def","props","shortDescription","title","keys","collection","name","fields","map","getFormDataFromState","state","getFormValue","getFormValueFromState","value","isValue","undefined","getStateFromValidForm","payload","getErrors","errors","list","filter","error","path","includes","length","getFirstError","getViewErrors","firstError","getViewModel","options","viewModel","isRequired","required","hideOptional","text","componentErrors","componentError","errorMessage","id","getDisplayStringFromFormValue","toString","getDisplayStringFromState","getContextValueFromFormValue","isState","values","Object","isFormValue","Array","isArray","getContextValueFromState","isFormState","getAllPossibleErrors","baseErrors","advancedSettingsErrors","onSubmit","_request","_metadata","_context","Promise","resolve","isRepeatState","every","isRepeatValue","itemId","isUploadState","isUploadValue","isGeospatialState","isGeospatialValue","uploadId"],"sources":["../../../../../src/server/plugins/engine/components/FormComponent.ts"],"sourcesContent":["import {\n type FormComponentsDef,\n type FormMetadata,\n type Item\n} from '@defra/forms-model'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { optionalText } from '~/src/server/plugins/engine/components/constants.js'\nimport {\n type FormContext,\n type FormRequestPayload\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type Feature,\n type FileState,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type FormValue,\n type GeospatialState,\n type RepeatItemState,\n type RepeatListState,\n type UploadState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class FormComponent extends ComponentBase {\n type: FormComponentsDef['type']\n hint: FormComponentsDef['hint']\n label: string\n\n isFormComponent = true\n isAppendageStateSingleObject = false\n\n constructor(\n def: FormComponentsDef,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { hint, type } = def\n\n this.type = type\n this.hint = hint\n this.label =\n 'shortDescription' in def && def.shortDescription\n ? def.shortDescription\n : def.title\n }\n\n get keys() {\n const { collection, name } = this\n\n if (collection) {\n const { fields } = collection\n return [name, ...fields.map(({ name }) => name)]\n }\n\n return [name]\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormDataFromState(state)\n }\n\n return {\n [name]: this.getFormValue(state[name])\n }\n }\n\n getFormValueFromState(state: FormSubmissionState): FormValue | FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormValueFromState(state)\n }\n\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { collection, name } = this\n\n if (collection) {\n return collection.getStateFromValidForm(payload)\n }\n\n return {\n [name]: this.getFormValue(payload[name]) ?? null\n }\n }\n\n getErrors(errors?: FormSubmissionError[]): FormSubmissionError[] | undefined {\n const { name } = this\n\n // Filter component and child errors only\n const list = errors?.filter(\n (error) =>\n error.name === name ||\n error.path.includes(name) ||\n this.keys.includes(error.name)\n )\n\n if (!list?.length) {\n return\n }\n\n return list\n }\n\n getFirstError(\n errors?: FormSubmissionError[]\n ): FormSubmissionError | undefined {\n return this.getErrors(errors)?.[0]\n }\n\n getViewErrors(\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const firstError = this.getFirstError(errors)\n return firstError && [firstError]\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const { hint, name, options = {}, title, viewModel } = this\n\n const isRequired = !('required' in options) || options.required !== false\n const hideOptional = 'optionalText' in options && options.optionalText\n const label = `${title}${!isRequired && !hideOptional ? optionalText : ''}`\n\n if (hint) {\n viewModel.hint = {\n text: hint\n }\n }\n\n // Filter component errors only\n const componentErrors = this.getErrors(errors)\n const componentError = this.getFirstError(componentErrors)\n\n if (componentErrors) {\n viewModel.errors = componentErrors\n }\n\n if (componentError) {\n viewModel.errorMessage = {\n text: componentError.text\n }\n }\n\n return {\n ...viewModel,\n label: {\n text: label\n },\n id: name,\n name,\n value: payload[name]\n }\n }\n\n getDisplayStringFromFormValue(value: FormValue | FormPayload): string {\n // Map selected values to text\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return this.isValue(value) ? value.toString() : ''\n }\n\n getDisplayStringFromState(state: FormSubmissionState): string {\n const value = this.getFormValueFromState(state)\n return this.getDisplayStringFromFormValue(value)\n }\n\n getContextValueFromFormValue(\n value: FormValue | FormPayload\n ): Item['value'] | Item['value'][] | null {\n // Filter object field values\n if (this.isState(value)) {\n const values = Object.values(value).filter(isFormValue)\n return values.length ? values : null\n }\n\n // Filter array field values\n if (this.isValue(value) && Array.isArray(value)) {\n return value.filter(isFormValue)\n }\n\n return this.isValue(value) ? value : null\n }\n\n getContextValueFromState(\n state: FormSubmissionState\n ): Item['value'] | Item['value'][] | null {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n isValue(\n value?: FormStateValue | FormState\n ): value is NonNullable<FormStateValue> {\n return isFormValue(value)\n }\n\n isState(value?: FormStateValue | FormState): value is FormState {\n return isFormState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FormComponent.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [],\n advancedSettingsErrors: []\n }\n }\n\n onSubmit(\n _request: FormRequestPayload,\n _metadata: FormMetadata,\n _context: FormContext\n ): Promise<void> {\n return Promise.resolve()\n }\n}\n\n/**\n * Check for form value\n */\nexport function isFormValue(\n value?: unknown\n): value is string | number | boolean {\n return (\n (typeof value === 'string' && value.length > 0) ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n )\n}\n\n/**\n * Check for form state with nested values\n */\nexport function isFormState(value?: unknown): value is FormState {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n // Skip empty objects\n return !!Object.values(value).length\n}\n\n/**\n * Check for repeat list state\n */\nexport function isRepeatState(value?: unknown): value is RepeatListState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isRepeatValue)\n}\n\n/**\n * Check for repeat list value\n */\nexport function isRepeatValue(value?: unknown): value is RepeatItemState {\n return isFormState(value) && typeof value.itemId === 'string'\n}\n\n/**\n * Check for upload state\n */\nexport function isUploadState(value?: unknown): value is UploadState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isUploadValue)\n}\n\n/**\n * Check for geospatial state\n */\nexport function isGeospatialState(value?: unknown): value is GeospatialState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isGeospatialValue)\n}\n\n/**\n * Check for upload state value\n */\nexport function isUploadValue(value?: unknown): value is FileState {\n return isFormState(value) && typeof value.uploadId === 'string'\n}\n\n/**\n * Check for geospatial state value\n */\nexport function isGeospatialValue(value?: unknown): value is Feature {\n return (\n isFormState(value) &&\n typeof value.type === 'string' &&\n value.type === 'Feature'\n )\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"FormComponent.js","names":["ComponentBase","optionalText","FormComponent","type","hint","label","isFormComponent","isAppendageStateSingleObject","constructor","def","props","getLabel","errorDescription","shortDescription","title","keys","collection","name","fields","map","getFormDataFromState","state","getFormValue","getFormValueFromState","value","isValue","undefined","getStateFromValidForm","payload","getErrors","errors","list","filter","error","path","includes","length","getFirstError","getViewErrors","firstError","getViewModel","options","viewModel","isRequired","required","hideOptional","text","componentErrors","componentError","errorMessage","id","getDisplayStringFromFormValue","toString","getDisplayStringFromState","getContextValueFromFormValue","isState","values","Object","isFormValue","Array","isArray","getContextValueFromState","isFormState","getAllPossibleErrors","baseErrors","advancedSettingsErrors","onSubmit","_request","_metadata","_context","Promise","resolve","isRepeatState","every","isRepeatValue","itemId","isUploadState","isUploadValue","isGeospatialState","isGeospatialValue","uploadId"],"sources":["../../../../../src/server/plugins/engine/components/FormComponent.ts"],"sourcesContent":["import {\n type FormComponentsDef,\n type FormMetadata,\n type Item\n} from '@defra/forms-model'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { optionalText } from '~/src/server/plugins/engine/components/constants.js'\nimport {\n type FormContext,\n type FormRequestPayload\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type Feature,\n type FileState,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type FormValue,\n type GeospatialState,\n type RepeatItemState,\n type RepeatListState,\n type UploadState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class FormComponent extends ComponentBase {\n type: FormComponentsDef['type']\n hint: FormComponentsDef['hint']\n label: string\n\n isFormComponent = true\n isAppendageStateSingleObject = false\n\n constructor(\n def: FormComponentsDef,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { hint, type } = def\n\n this.type = type\n this.hint = hint\n\n this.label = this.getLabel(def)\n }\n\n getLabel(def: FormComponentsDef) {\n if ('errorDescription' in def && def.errorDescription) {\n return def.errorDescription\n }\n\n if ('shortDescription' in def && def.shortDescription) {\n return def.shortDescription\n }\n\n return def.title\n }\n\n get keys() {\n const { collection, name } = this\n\n if (collection) {\n const { fields } = collection\n return [name, ...fields.map(({ name }) => name)]\n }\n\n return [name]\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormDataFromState(state)\n }\n\n return {\n [name]: this.getFormValue(state[name])\n }\n }\n\n getFormValueFromState(state: FormSubmissionState): FormValue | FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormValueFromState(state)\n }\n\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { collection, name } = this\n\n if (collection) {\n return collection.getStateFromValidForm(payload)\n }\n\n return {\n [name]: this.getFormValue(payload[name]) ?? null\n }\n }\n\n getErrors(errors?: FormSubmissionError[]): FormSubmissionError[] | undefined {\n const { name } = this\n\n // Filter component and child errors only\n const list = errors?.filter(\n (error) =>\n error.name === name ||\n error.path.includes(name) ||\n this.keys.includes(error.name)\n )\n\n if (!list?.length) {\n return\n }\n\n return list\n }\n\n getFirstError(\n errors?: FormSubmissionError[]\n ): FormSubmissionError | undefined {\n return this.getErrors(errors)?.[0]\n }\n\n getViewErrors(\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const firstError = this.getFirstError(errors)\n return firstError && [firstError]\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const { hint, name, options = {}, title, viewModel } = this\n\n const isRequired = !('required' in options) || options.required !== false\n const hideOptional = 'optionalText' in options && options.optionalText\n const label = `${title}${!isRequired && !hideOptional ? optionalText : ''}`\n\n if (hint) {\n viewModel.hint = {\n text: hint\n }\n }\n\n // Filter component errors only\n const componentErrors = this.getErrors(errors)\n const componentError = this.getFirstError(componentErrors)\n\n if (componentErrors) {\n viewModel.errors = componentErrors\n }\n\n if (componentError) {\n viewModel.errorMessage = {\n text: componentError.text\n }\n }\n\n return {\n ...viewModel,\n label: {\n text: label\n },\n id: name,\n name,\n value: payload[name]\n }\n }\n\n getDisplayStringFromFormValue(value: FormValue | FormPayload): string {\n // Map selected values to text\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return this.isValue(value) ? value.toString() : ''\n }\n\n getDisplayStringFromState(state: FormSubmissionState): string {\n const value = this.getFormValueFromState(state)\n return this.getDisplayStringFromFormValue(value)\n }\n\n getContextValueFromFormValue(\n value: FormValue | FormPayload\n ): Item['value'] | Item['value'][] | null {\n // Filter object field values\n if (this.isState(value)) {\n const values = Object.values(value).filter(isFormValue)\n return values.length ? values : null\n }\n\n // Filter array field values\n if (this.isValue(value) && Array.isArray(value)) {\n return value.filter(isFormValue)\n }\n\n return this.isValue(value) ? value : null\n }\n\n getContextValueFromState(\n state: FormSubmissionState\n ): Item['value'] | Item['value'][] | null {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n isValue(\n value?: FormStateValue | FormState\n ): value is NonNullable<FormStateValue> {\n return isFormValue(value)\n }\n\n isState(value?: FormStateValue | FormState): value is FormState {\n return isFormState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FormComponent.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [],\n advancedSettingsErrors: []\n }\n }\n\n onSubmit(\n _request: FormRequestPayload,\n _metadata: FormMetadata,\n _context: FormContext\n ): Promise<void> {\n return Promise.resolve()\n }\n}\n\n/**\n * Check for form value\n */\nexport function isFormValue(\n value?: unknown\n): value is string | number | boolean {\n return (\n (typeof value === 'string' && value.length > 0) ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n )\n}\n\n/**\n * Check for form state with nested values\n */\nexport function isFormState(value?: unknown): value is FormState {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n // Skip empty objects\n return !!Object.values(value).length\n}\n\n/**\n * Check for repeat list state\n */\nexport function isRepeatState(value?: unknown): value is RepeatListState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isRepeatValue)\n}\n\n/**\n * Check for repeat list value\n */\nexport function isRepeatValue(value?: unknown): value is RepeatItemState {\n return isFormState(value) && typeof value.itemId === 'string'\n}\n\n/**\n * Check for upload state\n */\nexport function isUploadState(value?: unknown): value is UploadState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isUploadValue)\n}\n\n/**\n * Check for geospatial state\n */\nexport function isGeospatialState(value?: unknown): value is GeospatialState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isGeospatialValue)\n}\n\n/**\n * Check for upload state value\n */\nexport function isUploadValue(value?: unknown): value is FileState {\n return isFormState(value) && typeof value.uploadId === 'string'\n}\n\n/**\n * Check for geospatial state value\n */\nexport function isGeospatialValue(value?: unknown): value is Feature {\n return (\n isFormState(value) &&\n typeof value.type === 'string' &&\n value.type === 'Feature'\n )\n}\n"],"mappings":"AAMA,SAASA,aAAa;AACtB,SAASC,YAAY;AAqBrB,OAAO,MAAMC,aAAa,SAASF,aAAa,CAAC;EAC/CG,IAAI;EACJC,IAAI;EACJC,KAAK;EAELC,eAAe,GAAG,IAAI;EACtBC,4BAA4B,GAAG,KAAK;EAEpCC,WAAWA,CACTC,GAAsB,EACtBC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEN,IAAI;MAAED;IAAK,CAAC,GAAGM,GAAG;IAE1B,IAAI,CAACN,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACC,IAAI,GAAGA,IAAI;IAEhB,IAAI,CAACC,KAAK,GAAG,IAAI,CAACM,QAAQ,CAACF,GAAG,CAAC;EACjC;EAEAE,QAAQA,CAACF,GAAsB,EAAE;IAC/B,IAAI,kBAAkB,IAAIA,GAAG,IAAIA,GAAG,CAACG,gBAAgB,EAAE;MACrD,OAAOH,GAAG,CAACG,gBAAgB;IAC7B;IAEA,IAAI,kBAAkB,IAAIH,GAAG,IAAIA,GAAG,CAACI,gBAAgB,EAAE;MACrD,OAAOJ,GAAG,CAACI,gBAAgB;IAC7B;IAEA,OAAOJ,GAAG,CAACK,KAAK;EAClB;EAEA,IAAIC,IAAIA,CAAA,EAAG;IACT,MAAM;MAAEC,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,MAAM;QAAEE;MAAO,CAAC,GAAGF,UAAU;MAC7B,OAAO,CAACC,IAAI,EAAE,GAAGC,MAAM,CAACC,GAAG,CAAC,CAAC;QAAEF;MAAK,CAAC,KAAKA,IAAI,CAAC,CAAC;IAClD;IAEA,OAAO,CAACA,IAAI,CAAC;EACf;EAEAG,oBAAoBA,CAACC,KAA0B,EAAe;IAC5D,MAAM;MAAEL,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,OAAOA,UAAU,CAACI,oBAAoB,CAACC,KAAK,CAAC;IAC/C;IAEA,OAAO;MACL,CAACJ,IAAI,GAAG,IAAI,CAACK,YAAY,CAACD,KAAK,CAACJ,IAAI,CAAC;IACvC,CAAC;EACH;EAEAM,qBAAqBA,CAACF,KAA0B,EAA2B;IACzE,MAAM;MAAEL,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,OAAOA,UAAU,CAACO,qBAAqB,CAACF,KAAK,CAAC;IAChD;IAEA,OAAO,IAAI,CAACC,YAAY,CAACD,KAAK,CAACJ,IAAI,CAAC,CAAC;EACvC;EAEAK,YAAYA,CAACE,KAAkC,EAAE;IAC/C,OAAO,IAAI,CAACC,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,GAAGE,SAAS;EAChD;EAEAC,qBAAqBA,CAACC,OAAoB,EAAa;IACrD,MAAM;MAAEZ,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,OAAOA,UAAU,CAACW,qBAAqB,CAACC,OAAO,CAAC;IAClD;IAEA,OAAO;MACL,CAACX,IAAI,GAAG,IAAI,CAACK,YAAY,CAACM,OAAO,CAACX,IAAI,CAAC,CAAC,IAAI;IAC9C,CAAC;EACH;EAEAY,SAASA,CAACC,MAA8B,EAAqC;IAC3E,MAAM;MAAEb;IAAK,CAAC,GAAG,IAAI;;IAErB;IACA,MAAMc,IAAI,GAAGD,MAAM,EAAEE,MAAM,CACxBC,KAAK,IACJA,KAAK,CAAChB,IAAI,KAAKA,IAAI,IACnBgB,KAAK,CAACC,IAAI,CAACC,QAAQ,CAAClB,IAAI,CAAC,IACzB,IAAI,CAACF,IAAI,CAACoB,QAAQ,CAACF,KAAK,CAAChB,IAAI,CACjC,CAAC;IAED,IAAI,CAACc,IAAI,EAAEK,MAAM,EAAE;MACjB;IACF;IAEA,OAAOL,IAAI;EACb;EAEAM,aAAaA,CACXP,MAA8B,EACG;IACjC,OAAO,IAAI,CAACD,SAAS,CAACC,MAAM,CAAC,GAAG,CAAC,CAAC;EACpC;EAEAQ,aAAaA,CACXR,MAA8B,EACK;IACnC,MAAMS,UAAU,GAAG,IAAI,CAACF,aAAa,CAACP,MAAM,CAAC;IAC7C,OAAOS,UAAU,IAAI,CAACA,UAAU,CAAC;EACnC;EAEAC,YAAYA,CAACZ,OAAoB,EAAEE,MAA8B,EAAE;IACjE,MAAM;MAAE1B,IAAI;MAAEa,IAAI;MAAEwB,OAAO,GAAG,CAAC,CAAC;MAAE3B,KAAK;MAAE4B;IAAU,CAAC,GAAG,IAAI;IAE3D,MAAMC,UAAU,GAAG,EAAE,UAAU,IAAIF,OAAO,CAAC,IAAIA,OAAO,CAACG,QAAQ,KAAK,KAAK;IACzE,MAAMC,YAAY,GAAG,cAAc,IAAIJ,OAAO,IAAIA,OAAO,CAACxC,YAAY;IACtE,MAAMI,KAAK,GAAG,GAAGS,KAAK,GAAG,CAAC6B,UAAU,IAAI,CAACE,YAAY,GAAG5C,YAAY,GAAG,EAAE,EAAE;IAE3E,IAAIG,IAAI,EAAE;MACRsC,SAAS,CAACtC,IAAI,GAAG;QACf0C,IAAI,EAAE1C;MACR,CAAC;IACH;;IAEA;IACA,MAAM2C,eAAe,GAAG,IAAI,CAAClB,SAAS,CAACC,MAAM,CAAC;IAC9C,MAAMkB,cAAc,GAAG,IAAI,CAACX,aAAa,CAACU,eAAe,CAAC;IAE1D,IAAIA,eAAe,EAAE;MACnBL,SAAS,CAACZ,MAAM,GAAGiB,eAAe;IACpC;IAEA,IAAIC,cAAc,EAAE;MAClBN,SAAS,CAACO,YAAY,GAAG;QACvBH,IAAI,EAAEE,cAAc,CAACF;MACvB,CAAC;IACH;IAEA,OAAO;MACL,GAAGJ,SAAS;MACZrC,KAAK,EAAE;QACLyC,IAAI,EAAEzC;MACR,CAAC;MACD6C,EAAE,EAAEjC,IAAI;MACRA,IAAI;MACJO,KAAK,EAAEI,OAAO,CAACX,IAAI;IACrB,CAAC;EACH;EAEAkC,6BAA6BA,CAAC3B,KAA8B,EAAU;IACpE;IACA;IACA,OAAO,IAAI,CAACC,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,CAAC4B,QAAQ,CAAC,CAAC,GAAG,EAAE;EACpD;EAEAC,yBAAyBA,CAAChC,KAA0B,EAAU;IAC5D,MAAMG,KAAK,GAAG,IAAI,CAACD,qBAAqB,CAACF,KAAK,CAAC;IAC/C,OAAO,IAAI,CAAC8B,6BAA6B,CAAC3B,KAAK,CAAC;EAClD;EAEA8B,4BAA4BA,CAC1B9B,KAA8B,EACU;IACxC;IACA,IAAI,IAAI,CAAC+B,OAAO,CAAC/B,KAAK,CAAC,EAAE;MACvB,MAAMgC,MAAM,GAAGC,MAAM,CAACD,MAAM,CAAChC,KAAK,CAAC,CAACQ,MAAM,CAAC0B,WAAW,CAAC;MACvD,OAAOF,MAAM,CAACpB,MAAM,GAAGoB,MAAM,GAAG,IAAI;IACtC;;IAEA;IACA,IAAI,IAAI,CAAC/B,OAAO,CAACD,KAAK,CAAC,IAAImC,KAAK,CAACC,OAAO,CAACpC,KAAK,CAAC,EAAE;MAC/C,OAAOA,KAAK,CAACQ,MAAM,CAAC0B,WAAW,CAAC;IAClC;IAEA,OAAO,IAAI,CAACjC,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,GAAG,IAAI;EAC3C;EAEAqC,wBAAwBA,CACtBxC,KAA0B,EACc;IACxC,MAAMG,KAAK,GAAG,IAAI,CAACD,qBAAqB,CAACF,KAAK,CAAC;IAE/C,OAAO,IAAI,CAACiC,4BAA4B,CAAC9B,KAAK,CAAC;EACjD;EAEAC,OAAOA,CACLD,KAAkC,EACI;IACtC,OAAOkC,WAAW,CAAClC,KAAK,CAAC;EAC3B;EAEA+B,OAAOA,CAAC/B,KAAkC,EAAsB;IAC9D,OAAOsC,WAAW,CAACtC,KAAK,CAAC;EAC3B;;EAEA;AACF;AACA;EACEuC,oBAAoBA,CAAA,EAA6B;IAC/C,OAAO7D,aAAa,CAAC6D,oBAAoB,CAAC,CAAC;EAC7C;;EAEA;AACF;AACA;EACE,OAAOA,oBAAoBA,CAAA,EAA6B;IACtD,OAAO;MACLC,UAAU,EAAE,EAAE;MACdC,sBAAsB,EAAE;IAC1B,CAAC;EACH;EAEAC,QAAQA,CACNC,QAA4B,EAC5BC,SAAuB,EACvBC,QAAqB,EACN;IACf,OAAOC,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;AACF;;AAEA;AACA;AACA;AACA,OAAO,SAASb,WAAWA,CACzBlC,KAAe,EACqB;EACpC,OACG,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACY,MAAM,GAAG,CAAC,IAC9C,OAAOZ,KAAK,KAAK,QAAQ,IACzB,OAAOA,KAAK,KAAK,SAAS;AAE9B;;AAEA;AACA;AACA;AACA,OAAO,SAASsC,WAAWA,CAACtC,KAAe,EAAsB;EAC/D,IAAIA,KAAK,KAAK,IAAI,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAImC,KAAK,CAACC,OAAO,CAACpC,KAAK,CAAC,EAAE;IACvE,OAAO,KAAK;EACd;;EAEA;EACA,OAAO,CAAC,CAACiC,MAAM,CAACD,MAAM,CAAChC,KAAK,CAAC,CAACY,MAAM;AACtC;;AAEA;AACA;AACA;AACA,OAAO,SAASoC,aAAaA,CAAChD,KAAe,EAA4B;EACvE,IAAI,CAACmC,KAAK,CAACC,OAAO,CAACpC,KAAK,CAAC,EAAE;IACzB,OAAO,KAAK;EACd;;EAEA;EACA,IAAI,CAACA,KAAK,CAACY,MAAM,EAAE;IACjB,OAAO,IAAI;EACb;EAEA,OAAOZ,KAAK,CAACiD,KAAK,CAACC,aAAa,CAAC;AACnC;;AAEA;AACA;AACA;AACA,OAAO,SAASA,aAAaA,CAAClD,KAAe,EAA4B;EACvE,OAAOsC,WAAW,CAACtC,KAAK,CAAC,IAAI,OAAOA,KAAK,CAACmD,MAAM,KAAK,QAAQ;AAC/D;;AAEA;AACA;AACA;AACA,OAAO,SAASC,aAAaA,CAACpD,KAAe,EAAwB;EACnE,IAAI,CAACmC,KAAK,CAACC,OAAO,CAACpC,KAAK,CAAC,EAAE;IACzB,OAAO,KAAK;EACd;;EAEA;EACA,IAAI,CAACA,KAAK,CAACY,MAAM,EAAE;IACjB,OAAO,IAAI;EACb;EAEA,OAAOZ,KAAK,CAACiD,KAAK,CAACI,aAAa,CAAC;AACnC;;AAEA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAACtD,KAAe,EAA4B;EAC3E,IAAI,CAACmC,KAAK,CAACC,OAAO,CAACpC,KAAK,CAAC,EAAE;IACzB,OAAO,KAAK;EACd;;EAEA;EACA,IAAI,CAACA,KAAK,CAACY,MAAM,EAAE;IACjB,OAAO,IAAI;EACb;EAEA,OAAOZ,KAAK,CAACiD,KAAK,CAACM,iBAAiB,CAAC;AACvC;;AAEA;AACA;AACA;AACA,OAAO,SAASF,aAAaA,CAACrD,KAAe,EAAsB;EACjE,OAAOsC,WAAW,CAACtC,KAAK,CAAC,IAAI,OAAOA,KAAK,CAACwD,QAAQ,KAAK,QAAQ;AACjE;;AAEA;AACA;AACA;AACA,OAAO,SAASD,iBAAiBA,CAACvD,KAAe,EAAoB;EACnE,OACEsC,WAAW,CAACtC,KAAK,CAAC,IAClB,OAAOA,KAAK,CAACrB,IAAI,KAAK,QAAQ,IAC9BqB,KAAK,CAACrB,IAAI,KAAK,SAAS;AAE5B","ignoreList":[]}
|
|
@@ -178,10 +178,10 @@ export class MonthYearField extends FormComponent {
|
|
|
178
178
|
template: '{{#label}} must include a year'
|
|
179
179
|
}],
|
|
180
180
|
advancedSettingsErrors: [{
|
|
181
|
-
type: '
|
|
181
|
+
type: 'dateEarliest',
|
|
182
182
|
template: messageTemplate.dateMin
|
|
183
183
|
}, {
|
|
184
|
-
type: '
|
|
184
|
+
type: 'dateLatest',
|
|
185
185
|
template: messageTemplate.dateMax
|
|
186
186
|
}]
|
|
187
187
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MonthYearField.js","names":["ComponentType","format","isValid","parse","ComponentCollection","FormComponent","isFormState","isFormValue","NumberField","parseStrictDate","messageTemplate","convertToLanguageMessages","MonthYearField","constructor","def","props","name","options","isRequired","required","customValidationMessages","objectMissing","dateFormat","collection","type","title","schema","min","max","precision","optionalText","classes","parent","custom","getValidatorMonthYear","peers","formSchema","stateSchema","getFormValueFromState","state","value","isMonthYear","undefined","getDisplayStringFromFormValue","date","Date","setMonth","month","monthString","toLocaleString","year","getDisplayStringFromState","getContextValueFromFormValue","getContextValueFromState","getViewModel","payload","errors","viewModel","fieldset","label","hasError","some","error","items","map","model","errorMessage","toString","text","trim","id","legend","isState","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors","dateMin","dateMax","isNumber","component","validator","helpers","values","getStateFromValidForm","context","missing","keys","key","earliestDate","earliestMonthYear","limit","latestDate","latestMonthYear"],"sources":["../../../../../src/server/plugins/engine/components/MonthYearField.ts"],"sourcesContent":["import { ComponentType, type MonthYearFieldComponent } from '@defra/forms-model'\nimport { format, isValid, parse } from 'date-fns'\nimport {\n type Context,\n type CustomValidator,\n type LanguageMessages,\n type ObjectSchema\n} from 'joi'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nimport {\n type DateInputItem,\n type MonthYearState\n} from '~/src/server/plugins/engine/components/types.js'\nimport { parseStrictDate } from '~/src/server/plugins/engine/date-helper.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { convertToLanguageMessages } from '~/src/server/utils/type-utils.js'\n\nexport class MonthYearField extends FormComponent {\n declare options: MonthYearFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: MonthYearFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options } = def\n\n const isRequired = options.required !== false\n\n const customValidationMessages: LanguageMessages =\n convertToLanguageMessages({\n 'any.required': messageTemplate.objectMissing,\n 'number.base': messageTemplate.objectMissing,\n 'number.precision': messageTemplate.dateFormat,\n 'number.integer': messageTemplate.dateFormat,\n 'number.unsafe': messageTemplate.dateFormat,\n 'number.min': messageTemplate.dateFormat,\n 'number.max': messageTemplate.dateFormat\n })\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.NumberField,\n name: `${name}__month`,\n title: 'Month',\n schema: { min: 1, max: 12, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-2',\n customValidationMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__year`,\n title: 'Year',\n schema: { min: 1000, max: 3000, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-4',\n customValidationMessages\n }\n }\n ],\n { ...props, parent: this },\n {\n custom: getValidatorMonthYear(this),\n peers: [`${name}__month`, `${name}__year`]\n }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return MonthYearField.isMonthYear(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(value: MonthYearState | undefined): string {\n if (!value) {\n return ''\n }\n\n const date = new Date()\n date.setMonth(value.month - 1)\n\n const monthString = date.toLocaleString('default', { month: 'long' })\n return `${monthString} ${value.year}`\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\n }\n\n getContextValueFromFormValue(\n value: MonthYearState | undefined\n ): string | null {\n if (\n !value ||\n !isValid(\n parseStrictDate(\n value,\n `${value.year}-${value.month}-01`,\n 'yyyy-MM-dd',\n new Date()\n )\n )\n ) {\n return null\n }\n\n return format(`${value.year}-${value.month}-01`, 'yyyy-MM')\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const { collection, name } = this\n\n const viewModel = super.getViewModel(payload, errors)\n let { fieldset, label } = viewModel\n\n // Check for component errors only\n const hasError = errors?.some((error) => error.name === name)\n\n // Use the component collection to generate the subitems\n const items: DateInputItem[] = collection\n .getViewModel(payload, errors)\n .map(({ model }) => {\n let { label, type, value, classes, errorMessage } = model\n\n if (label) {\n label.toString = () => label.text // Date component uses string labels\n }\n\n if (hasError || errorMessage) {\n classes = `${classes} govuk-input--error`.trim()\n }\n\n // Allow any `toString()`-able value so non-numeric\n // values are shown alongside their error messages\n if (!isFormValue(value)) {\n value = undefined\n }\n\n return {\n label,\n id: model.id,\n name: model.name,\n type,\n value,\n classes\n }\n })\n\n fieldset ??= {\n legend: {\n text: label.text,\n classes: 'govuk-fieldset__legend--m'\n }\n }\n\n return {\n ...viewModel,\n fieldset,\n items\n }\n }\n\n isState(value?: FormStateValue | FormState) {\n return MonthYearField.isMonthYear(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return MonthYearField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.required },\n {\n type: 'dateFormatMonth',\n template: '{{#label}} must include a month'\n },\n { type: 'dateFormatYear', template: '{{#label}} must include a year' }\n ],\n advancedSettingsErrors: [\n { type: 'dateMin', template: messageTemplate.dateMin },\n { type: 'dateMax', template: messageTemplate.dateMax }\n ]\n }\n }\n\n static isMonthYear(\n value?: FormStateValue | FormState\n ): value is MonthYearState {\n return (\n isFormState(value) &&\n NumberField.isNumber(value.month) &&\n NumberField.isNumber(value.year)\n )\n }\n}\n\nexport function getValidatorMonthYear(component: MonthYearField) {\n const validator: CustomValidator = (payload: FormPayload, helpers) => {\n const { collection, name, options } = component\n\n const values = component.getFormValueFromState(\n component.getStateFromValidForm(payload)\n )\n\n const context: Context = {\n missing: collection.keys,\n key: name\n }\n\n if (!component.isState(values)) {\n return options.required !== false\n ? helpers.error('object.required', context)\n : payload\n }\n\n const date = parse(\n `${values.year}-${values.month}-01`,\n 'yyyy-MM-dd',\n new Date()\n )\n\n if (!isValid(date)) {\n return helpers.error('date.format', context)\n }\n\n // Minimum date from today\n const earliestDate = options.earliestMonthYear\n ? new Date(`${options.earliestMonthYear}-01`)\n : undefined\n\n if (earliestDate && date < earliestDate) {\n return helpers.error('date.min', { ...context, limit: earliestDate })\n }\n\n // Maximum date from today\n const latestDate = options.latestMonthYear\n ? new Date(`${options.latestMonthYear}-01`)\n : undefined\n\n if (latestDate && date > latestDate) {\n return helpers.error('date.max', { ...context, limit: latestDate })\n }\n\n return payload\n }\n\n return validator\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"MonthYearField.js","names":["ComponentType","format","isValid","parse","ComponentCollection","FormComponent","isFormState","isFormValue","NumberField","parseStrictDate","messageTemplate","convertToLanguageMessages","MonthYearField","constructor","def","props","name","options","isRequired","required","customValidationMessages","objectMissing","dateFormat","collection","type","title","schema","min","max","precision","optionalText","classes","parent","custom","getValidatorMonthYear","peers","formSchema","stateSchema","getFormValueFromState","state","value","isMonthYear","undefined","getDisplayStringFromFormValue","date","Date","setMonth","month","monthString","toLocaleString","year","getDisplayStringFromState","getContextValueFromFormValue","getContextValueFromState","getViewModel","payload","errors","viewModel","fieldset","label","hasError","some","error","items","map","model","errorMessage","toString","text","trim","id","legend","isState","getAllPossibleErrors","baseErrors","template","advancedSettingsErrors","dateMin","dateMax","isNumber","component","validator","helpers","values","getStateFromValidForm","context","missing","keys","key","earliestDate","earliestMonthYear","limit","latestDate","latestMonthYear"],"sources":["../../../../../src/server/plugins/engine/components/MonthYearField.ts"],"sourcesContent":["import { ComponentType, type MonthYearFieldComponent } from '@defra/forms-model'\nimport { format, isValid, parse } from 'date-fns'\nimport {\n type Context,\n type CustomValidator,\n type LanguageMessages,\n type ObjectSchema\n} from 'joi'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nimport {\n type DateInputItem,\n type MonthYearState\n} from '~/src/server/plugins/engine/components/types.js'\nimport { parseStrictDate } from '~/src/server/plugins/engine/date-helper.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { convertToLanguageMessages } from '~/src/server/utils/type-utils.js'\n\nexport class MonthYearField extends FormComponent {\n declare options: MonthYearFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: MonthYearFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options } = def\n\n const isRequired = options.required !== false\n\n const customValidationMessages: LanguageMessages =\n convertToLanguageMessages({\n 'any.required': messageTemplate.objectMissing,\n 'number.base': messageTemplate.objectMissing,\n 'number.precision': messageTemplate.dateFormat,\n 'number.integer': messageTemplate.dateFormat,\n 'number.unsafe': messageTemplate.dateFormat,\n 'number.min': messageTemplate.dateFormat,\n 'number.max': messageTemplate.dateFormat\n })\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.NumberField,\n name: `${name}__month`,\n title: 'Month',\n schema: { min: 1, max: 12, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-2',\n customValidationMessages\n }\n },\n {\n type: ComponentType.NumberField,\n name: `${name}__year`,\n title: 'Year',\n schema: { min: 1000, max: 3000, precision: 0 },\n options: {\n required: isRequired,\n optionalText: true,\n classes: 'govuk-input--width-4',\n customValidationMessages\n }\n }\n ],\n { ...props, parent: this },\n {\n custom: getValidatorMonthYear(this),\n peers: [`${name}__month`, `${name}__year`]\n }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return MonthYearField.isMonthYear(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(value: MonthYearState | undefined): string {\n if (!value) {\n return ''\n }\n\n const date = new Date()\n date.setMonth(value.month - 1)\n\n const monthString = date.toLocaleString('default', { month: 'long' })\n return `${monthString} ${value.year}`\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\n }\n\n getContextValueFromFormValue(\n value: MonthYearState | undefined\n ): string | null {\n if (\n !value ||\n !isValid(\n parseStrictDate(\n value,\n `${value.year}-${value.month}-01`,\n 'yyyy-MM-dd',\n new Date()\n )\n )\n ) {\n return null\n }\n\n return format(`${value.year}-${value.month}-01`, 'yyyy-MM')\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const { collection, name } = this\n\n const viewModel = super.getViewModel(payload, errors)\n let { fieldset, label } = viewModel\n\n // Check for component errors only\n const hasError = errors?.some((error) => error.name === name)\n\n // Use the component collection to generate the subitems\n const items: DateInputItem[] = collection\n .getViewModel(payload, errors)\n .map(({ model }) => {\n let { label, type, value, classes, errorMessage } = model\n\n if (label) {\n label.toString = () => label.text // Date component uses string labels\n }\n\n if (hasError || errorMessage) {\n classes = `${classes} govuk-input--error`.trim()\n }\n\n // Allow any `toString()`-able value so non-numeric\n // values are shown alongside their error messages\n if (!isFormValue(value)) {\n value = undefined\n }\n\n return {\n label,\n id: model.id,\n name: model.name,\n type,\n value,\n classes\n }\n })\n\n fieldset ??= {\n legend: {\n text: label.text,\n classes: 'govuk-fieldset__legend--m'\n }\n }\n\n return {\n ...viewModel,\n fieldset,\n items\n }\n }\n\n isState(value?: FormStateValue | FormState) {\n return MonthYearField.isMonthYear(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return MonthYearField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.required },\n {\n type: 'dateFormatMonth',\n template: '{{#label}} must include a month'\n },\n { type: 'dateFormatYear', template: '{{#label}} must include a year' }\n ],\n advancedSettingsErrors: [\n { type: 'dateEarliest', template: messageTemplate.dateMin },\n { type: 'dateLatest', template: messageTemplate.dateMax }\n ]\n }\n }\n\n static isMonthYear(\n value?: FormStateValue | FormState\n ): value is MonthYearState {\n return (\n isFormState(value) &&\n NumberField.isNumber(value.month) &&\n NumberField.isNumber(value.year)\n )\n }\n}\n\nexport function getValidatorMonthYear(component: MonthYearField) {\n const validator: CustomValidator = (payload: FormPayload, helpers) => {\n const { collection, name, options } = component\n\n const values = component.getFormValueFromState(\n component.getStateFromValidForm(payload)\n )\n\n const context: Context = {\n missing: collection.keys,\n key: name\n }\n\n if (!component.isState(values)) {\n return options.required !== false\n ? helpers.error('object.required', context)\n : payload\n }\n\n const date = parse(\n `${values.year}-${values.month}-01`,\n 'yyyy-MM-dd',\n new Date()\n )\n\n if (!isValid(date)) {\n return helpers.error('date.format', context)\n }\n\n // Minimum date from today\n const earliestDate = options.earliestMonthYear\n ? new Date(`${options.earliestMonthYear}-01`)\n : undefined\n\n if (earliestDate && date < earliestDate) {\n return helpers.error('date.min', { ...context, limit: earliestDate })\n }\n\n // Maximum date from today\n const latestDate = options.latestMonthYear\n ? new Date(`${options.latestMonthYear}-01`)\n : undefined\n\n if (latestDate && date > latestDate) {\n return helpers.error('date.max', { ...context, limit: latestDate })\n }\n\n return payload\n }\n\n return validator\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type UkAddressFieldComponent } from '@defra/forms-model';
|
|
2
2
|
import { type ObjectSchema } from 'joi';
|
|
3
3
|
import { ComponentCollection } from '../../../../server/plugins/engine/components/ComponentCollection.js';
|
|
4
4
|
import { FormComponent } from '../../../../server/plugins/engine/components/FormComponent.js';
|
|
@@ -9,7 +9,6 @@ export declare class UkAddressField extends FormComponent {
|
|
|
9
9
|
formSchema: ObjectSchema<FormPayload>;
|
|
10
10
|
stateSchema: ObjectSchema<FormState>;
|
|
11
11
|
collection: ComponentCollection;
|
|
12
|
-
shortDescription: FormComponentsDef['shortDescription'];
|
|
13
12
|
constructor(def: UkAddressFieldComponent, props: ConstructorParameters<typeof FormComponent>[1]);
|
|
14
13
|
getFormValueFromState(state: FormSubmissionState): UkAddressState | undefined;
|
|
15
14
|
getContextValueFromFormValue(value: UkAddressState | undefined): string[] | null;
|
|
@@ -5,13 +5,11 @@ import { FormComponent, isFormState } from "./FormComponent.js";
|
|
|
5
5
|
import { TextField } from "./TextField.js";
|
|
6
6
|
import { dispatch } from "../../postcode-lookup/routes/index.js";
|
|
7
7
|
export class UkAddressField extends FormComponent {
|
|
8
|
-
shortDescription;
|
|
9
8
|
constructor(def, props) {
|
|
10
9
|
super(def, props);
|
|
11
10
|
const {
|
|
12
11
|
name,
|
|
13
|
-
options
|
|
14
|
-
shortDescription
|
|
12
|
+
options
|
|
15
13
|
} = def;
|
|
16
14
|
const isRequired = options.required !== false;
|
|
17
15
|
const hideOptional = !!options.optionalText;
|
|
@@ -94,7 +92,6 @@ export class UkAddressField extends FormComponent {
|
|
|
94
92
|
this.options = options;
|
|
95
93
|
this.formSchema = this.collection.formSchema;
|
|
96
94
|
this.stateSchema = this.collection.stateSchema;
|
|
97
|
-
this.shortDescription = shortDescription;
|
|
98
95
|
}
|
|
99
96
|
getFormValueFromState(state) {
|
|
100
97
|
const value = super.getFormValueFromState(state);
|
|
@@ -129,13 +126,13 @@ export class UkAddressField extends FormComponent {
|
|
|
129
126
|
if (this.shouldUsePostcodeLookup() && uniqueErrors?.length) {
|
|
130
127
|
const {
|
|
131
128
|
name,
|
|
132
|
-
|
|
129
|
+
label
|
|
133
130
|
} = this;
|
|
134
131
|
return [{
|
|
135
132
|
name,
|
|
136
133
|
path: [name],
|
|
137
134
|
href: `#${name}`,
|
|
138
|
-
text: `Enter ${lowerFirst(
|
|
135
|
+
text: `Enter ${lowerFirst(label)}`
|
|
139
136
|
}];
|
|
140
137
|
}
|
|
141
138
|
return uniqueErrors;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UkAddressField.js","names":["ComponentType","lowerFirst","ComponentCollection","FormComponent","isFormState","TextField","dispatch","UkAddressField","shortDescription","constructor","def","props","name","options","isRequired","required","hideOptional","optionalText","hideTitle","collection","type","title","schema","classes","max","autocomplete","regex","parent","formSchema","stateSchema","getFormValueFromState","state","value","isState","undefined","getContextValueFromFormValue","Object","entries","filter","key","Boolean","map","getContextValueFromState","getDisplayStringFromFormValue","join","getDisplayStringFromState","getViewErrors","errors","uniqueErrors","getErrors","error","index","self","findIndex","err","shouldUsePostcodeLookup","length","path","href","text","getViewModel","payload","viewModel","fieldset","hint","label","legend","id","attributes","components","uprn","at","Error","model","formGroup","usePostcodeLookup","isUkAddress","getAllPossibleErrors","ordnanceSurveyApiKey","baseErrors","template","advancedSettingsErrors","isText","addressLine1","town","postcode","dispatcher","request","h","args","controller","component","formName","componentName","componentHint","componentTitle","step","actionArgs","sourceUrl"],"sources":["../../../../../src/server/plugins/engine/components/UkAddressField.ts"],"sourcesContent":["import {\n ComponentType,\n type FormComponentsDef,\n type UkAddressFieldComponent\n} from '@defra/forms-model'\nimport { type ObjectSchema } from 'joi'\nimport lowerFirst from 'lodash/lowerFirst.js'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nimport { type QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'\nimport {\n type FormRequestPayload,\n type FormResponseToolkit\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type PostcodeLookupExternalArgs\n} from '~/src/server/plugins/engine/types.js'\nimport { dispatch } from '~/src/server/plugins/postcode-lookup/routes/index.js'\n\nexport class UkAddressField extends FormComponent {\n declare options: UkAddressFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n shortDescription: FormComponentsDef['shortDescription']\n\n constructor(\n def: UkAddressFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options, shortDescription } = def\n\n const isRequired = options.required !== false\n const hideOptional = !!options.optionalText\n const hideTitle = !!options.hideTitle\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.TextField,\n name: `${name}__uprn`,\n title: 'UPRN',\n schema: {},\n options: {\n required: false,\n classes: 'hidden'\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__addressLine1`,\n title: 'Address line 1',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-line1',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__addressLine2`,\n title: 'Address line 2',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-line2',\n required: false,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__town`,\n title: 'Town or city',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-level2',\n classes: 'govuk-!-width-two-thirds',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__county`,\n title: 'County',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-level1',\n required: false,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__postcode`,\n title: 'Postcode',\n schema: {\n regex: '^[a-zA-Z]{1,2}\\\\d[a-zA-Z\\\\d]?\\\\s?\\\\d[a-zA-Z]{2}$'\n },\n options: {\n autocomplete: 'postal-code',\n classes: 'govuk-input--width-10',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n }\n ],\n { ...props, parent: this }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n this.shortDescription = shortDescription\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return this.isState(value) ? value : undefined\n }\n\n getContextValueFromFormValue(value: UkAddressState | undefined) {\n if (!value) {\n return null\n }\n\n return Object.entries(value)\n .filter(([key, value]) => key !== 'uprn' && Boolean(value))\n .map(([, value]) => value)\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getDisplayStringFromFormValue(value: UkAddressState | undefined): string {\n return this.getContextValueFromFormValue(value)?.join(', ') ?? ''\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\n }\n\n /**\n * Returns one error per child field\n */\n getViewErrors(\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const uniqueErrors = this.getErrors(errors)?.filter(\n (error, index, self) =>\n index === self.findIndex((err) => err.name === error.name)\n )\n\n // When using postcode lookup, the address fields are hidden\n // so we replace any individual validation messages with a single one\n if (this.shouldUsePostcodeLookup() && uniqueErrors?.length) {\n const { name, shortDescription } = this\n\n return [\n {\n name,\n path: [name],\n href: `#${name}`,\n text: `Enter ${lowerFirst(shortDescription)}`\n }\n ]\n }\n\n return uniqueErrors\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const { collection, name, options } = this\n\n const viewModel = super.getViewModel(payload, errors)\n let { fieldset, hint, label } = viewModel\n\n fieldset ??= {\n legend: {\n text: label.text,\n\n /**\n * For screen readers, only hide legend visually. This can be overridden\n * by single component {@link QuestionPageController | `showTitle` handling}\n */\n classes: options.hideTitle\n ? 'govuk-visually-hidden'\n : 'govuk-fieldset__legend--m'\n }\n }\n\n if (hint) {\n hint.id ??= `${name}-hint`\n fieldset.attributes ??= {\n 'aria-describedby': hint.id\n }\n }\n\n const components = collection.getViewModel(payload, errors)\n\n // Hide UPRN\n const uprn = components.at(0)\n\n if (!uprn) {\n throw new Error('No UPRN')\n }\n\n uprn.model.formGroup = { classes: 'app-hidden' }\n\n // Postcode lookup\n const usePostcodeLookup = this.shouldUsePostcodeLookup()\n\n const value = usePostcodeLookup\n ? this.getDisplayStringFromState(payload)\n : undefined\n\n return {\n ...viewModel,\n value,\n fieldset,\n components,\n usePostcodeLookup\n }\n }\n\n isState(value?: FormStateValue | FormState): value is UkAddressState {\n return UkAddressField.isUkAddress(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return UkAddressField.getAllPossibleErrors()\n }\n\n private shouldUsePostcodeLookup() {\n return !!(this.options.usePostcodeLookup && this.model.ordnanceSurveyApiKey)\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: 'Enter address line 1' },\n { type: 'required', template: 'Enter town or city' },\n { type: 'required', template: 'Enter postcode' },\n { type: 'format', template: 'Enter valid postcode' }\n ],\n advancedSettingsErrors: []\n }\n }\n\n static isUkAddress(\n value?: FormStateValue | FormState\n ): value is UkAddressState {\n return (\n isFormState(value) &&\n TextField.isText(value.addressLine1) &&\n TextField.isText(value.town) &&\n TextField.isText(value.postcode)\n )\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n static async dispatcher(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n args: PostcodeLookupExternalArgs\n ) {\n const { controller, component } = args\n\n return dispatch(request, h, {\n formName: controller.model.name,\n componentName: component.name,\n componentHint: component.hint,\n componentTitle: component.title || controller.title,\n step: args.actionArgs.step,\n sourceUrl: args.sourceUrl\n })\n }\n}\n\nexport interface UkAddressState extends Record<string, string> {\n uprn: string\n addressLine1: string\n addressLine2: string\n town: string\n county: string\n postcode: string\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"UkAddressField.js","names":["ComponentType","lowerFirst","ComponentCollection","FormComponent","isFormState","TextField","dispatch","UkAddressField","constructor","def","props","name","options","isRequired","required","hideOptional","optionalText","hideTitle","collection","type","title","schema","classes","max","autocomplete","regex","parent","formSchema","stateSchema","getFormValueFromState","state","value","isState","undefined","getContextValueFromFormValue","Object","entries","filter","key","Boolean","map","getContextValueFromState","getDisplayStringFromFormValue","join","getDisplayStringFromState","getViewErrors","errors","uniqueErrors","getErrors","error","index","self","findIndex","err","shouldUsePostcodeLookup","length","label","path","href","text","getViewModel","payload","viewModel","fieldset","hint","legend","id","attributes","components","uprn","at","Error","model","formGroup","usePostcodeLookup","isUkAddress","getAllPossibleErrors","ordnanceSurveyApiKey","baseErrors","template","advancedSettingsErrors","isText","addressLine1","town","postcode","dispatcher","request","h","args","controller","component","formName","componentName","componentHint","componentTitle","step","actionArgs","sourceUrl"],"sources":["../../../../../src/server/plugins/engine/components/UkAddressField.ts"],"sourcesContent":["import { ComponentType, type UkAddressFieldComponent } from '@defra/forms-model'\nimport { type ObjectSchema } from 'joi'\nimport lowerFirst from 'lodash/lowerFirst.js'\n\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport {\n FormComponent,\n isFormState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nimport { type QuestionPageController } from '~/src/server/plugins/engine/pageControllers/QuestionPageController.js'\nimport {\n type FormRequestPayload,\n type FormResponseToolkit\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type PostcodeLookupExternalArgs\n} from '~/src/server/plugins/engine/types.js'\nimport { dispatch } from '~/src/server/plugins/postcode-lookup/routes/index.js'\n\nexport class UkAddressField extends FormComponent {\n declare options: UkAddressFieldComponent['options']\n declare formSchema: ObjectSchema<FormPayload>\n declare stateSchema: ObjectSchema<FormState>\n declare collection: ComponentCollection\n\n constructor(\n def: UkAddressFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { name, options } = def\n\n const isRequired = options.required !== false\n const hideOptional = !!options.optionalText\n const hideTitle = !!options.hideTitle\n\n this.collection = new ComponentCollection(\n [\n {\n type: ComponentType.TextField,\n name: `${name}__uprn`,\n title: 'UPRN',\n schema: {},\n options: {\n required: false,\n classes: 'hidden'\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__addressLine1`,\n title: 'Address line 1',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-line1',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__addressLine2`,\n title: 'Address line 2',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-line2',\n required: false,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__town`,\n title: 'Town or city',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-level2',\n classes: 'govuk-!-width-two-thirds',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__county`,\n title: 'County',\n schema: { max: 100 },\n options: {\n autocomplete: 'address-level1',\n required: false,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n },\n {\n type: ComponentType.TextField,\n name: `${name}__postcode`,\n title: 'Postcode',\n schema: {\n regex: '^[a-zA-Z]{1,2}\\\\d[a-zA-Z\\\\d]?\\\\s?\\\\d[a-zA-Z]{2}$'\n },\n options: {\n autocomplete: 'postal-code',\n classes: 'govuk-input--width-10',\n required: isRequired,\n optionalText: !isRequired && (hideOptional || !hideTitle)\n }\n }\n ],\n { ...props, parent: this }\n )\n\n this.options = options\n this.formSchema = this.collection.formSchema\n this.stateSchema = this.collection.stateSchema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const value = super.getFormValueFromState(state)\n return this.isState(value) ? value : undefined\n }\n\n getContextValueFromFormValue(value: UkAddressState | undefined) {\n if (!value) {\n return null\n }\n\n return Object.entries(value)\n .filter(([key, value]) => key !== 'uprn' && Boolean(value))\n .map(([, value]) => value)\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n getDisplayStringFromFormValue(value: UkAddressState | undefined): string {\n return this.getContextValueFromFormValue(value)?.join(', ') ?? ''\n }\n\n getDisplayStringFromState(state: FormSubmissionState) {\n const value = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(value)\n }\n\n /**\n * Returns one error per child field\n */\n getViewErrors(\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const uniqueErrors = this.getErrors(errors)?.filter(\n (error, index, self) =>\n index === self.findIndex((err) => err.name === error.name)\n )\n\n // When using postcode lookup, the address fields are hidden\n // so we replace any individual validation messages with a single one\n if (this.shouldUsePostcodeLookup() && uniqueErrors?.length) {\n const { name, label } = this\n\n return [\n {\n name,\n path: [name],\n href: `#${name}`,\n text: `Enter ${lowerFirst(label)}`\n }\n ]\n }\n\n return uniqueErrors\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const { collection, name, options } = this\n\n const viewModel = super.getViewModel(payload, errors)\n let { fieldset, hint, label } = viewModel\n\n fieldset ??= {\n legend: {\n text: label.text,\n\n /**\n * For screen readers, only hide legend visually. This can be overridden\n * by single component {@link QuestionPageController | `showTitle` handling}\n */\n classes: options.hideTitle\n ? 'govuk-visually-hidden'\n : 'govuk-fieldset__legend--m'\n }\n }\n\n if (hint) {\n hint.id ??= `${name}-hint`\n fieldset.attributes ??= {\n 'aria-describedby': hint.id\n }\n }\n\n const components = collection.getViewModel(payload, errors)\n\n // Hide UPRN\n const uprn = components.at(0)\n\n if (!uprn) {\n throw new Error('No UPRN')\n }\n\n uprn.model.formGroup = { classes: 'app-hidden' }\n\n // Postcode lookup\n const usePostcodeLookup = this.shouldUsePostcodeLookup()\n\n const value = usePostcodeLookup\n ? this.getDisplayStringFromState(payload)\n : undefined\n\n return {\n ...viewModel,\n value,\n fieldset,\n components,\n usePostcodeLookup\n }\n }\n\n isState(value?: FormStateValue | FormState): value is UkAddressState {\n return UkAddressField.isUkAddress(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return UkAddressField.getAllPossibleErrors()\n }\n\n private shouldUsePostcodeLookup() {\n return !!(this.options.usePostcodeLookup && this.model.ordnanceSurveyApiKey)\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: 'Enter address line 1' },\n { type: 'required', template: 'Enter town or city' },\n { type: 'required', template: 'Enter postcode' },\n { type: 'format', template: 'Enter valid postcode' }\n ],\n advancedSettingsErrors: []\n }\n }\n\n static isUkAddress(\n value?: FormStateValue | FormState\n ): value is UkAddressState {\n return (\n isFormState(value) &&\n TextField.isText(value.addressLine1) &&\n TextField.isText(value.town) &&\n TextField.isText(value.postcode)\n )\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n static async dispatcher(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n args: PostcodeLookupExternalArgs\n ) {\n const { controller, component } = args\n\n return dispatch(request, h, {\n formName: controller.model.name,\n componentName: component.name,\n componentHint: component.hint,\n componentTitle: component.title || controller.title,\n step: args.actionArgs.step,\n sourceUrl: args.sourceUrl\n })\n }\n}\n\nexport interface UkAddressState extends Record<string, string> {\n uprn: string\n addressLine1: string\n addressLine2: string\n town: string\n county: string\n postcode: string\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -230,8 +230,8 @@ export class DatePartsField extends FormComponent {
|
|
|
230
230
|
advancedSettingsErrors: [
|
|
231
231
|
{ type: 'dateMin', template: messageTemplate.dateMin },
|
|
232
232
|
{ type: 'dateMax', template: messageTemplate.dateMax },
|
|
233
|
-
{ type: '
|
|
234
|
-
{ type: '
|
|
233
|
+
{ type: 'dateEarliest', template: messageTemplate.dateMin },
|
|
234
|
+
{ type: 'dateLatest', template: messageTemplate.dateMax }
|
|
235
235
|
]
|
|
236
236
|
}
|
|
237
237
|
}
|
|
@@ -44,10 +44,20 @@ export class FormComponent extends ComponentBase {
|
|
|
44
44
|
|
|
45
45
|
this.type = type
|
|
46
46
|
this.hint = hint
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
|
|
48
|
+
this.label = this.getLabel(def)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
getLabel(def: FormComponentsDef) {
|
|
52
|
+
if ('errorDescription' in def && def.errorDescription) {
|
|
53
|
+
return def.errorDescription
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if ('shortDescription' in def && def.shortDescription) {
|
|
57
|
+
return def.shortDescription
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return def.title
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
get keys() {
|
|
@@ -223,8 +223,8 @@ export class MonthYearField extends FormComponent {
|
|
|
223
223
|
{ type: 'dateFormatYear', template: '{{#label}} must include a year' }
|
|
224
224
|
],
|
|
225
225
|
advancedSettingsErrors: [
|
|
226
|
-
{ type: '
|
|
227
|
-
{ type: '
|
|
226
|
+
{ type: 'dateEarliest', template: messageTemplate.dateMin },
|
|
227
|
+
{ type: 'dateLatest', template: messageTemplate.dateMax }
|
|
228
228
|
]
|
|
229
229
|
}
|
|
230
230
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ComponentType,
|
|
3
|
-
type FormComponentsDef,
|
|
4
|
-
type UkAddressFieldComponent
|
|
5
|
-
} from '@defra/forms-model'
|
|
1
|
+
import { ComponentType, type UkAddressFieldComponent } from '@defra/forms-model'
|
|
6
2
|
import { type ObjectSchema } from 'joi'
|
|
7
3
|
import lowerFirst from 'lodash/lowerFirst.js'
|
|
8
4
|
|
|
@@ -34,15 +30,13 @@ export class UkAddressField extends FormComponent {
|
|
|
34
30
|
declare stateSchema: ObjectSchema<FormState>
|
|
35
31
|
declare collection: ComponentCollection
|
|
36
32
|
|
|
37
|
-
shortDescription: FormComponentsDef['shortDescription']
|
|
38
|
-
|
|
39
33
|
constructor(
|
|
40
34
|
def: UkAddressFieldComponent,
|
|
41
35
|
props: ConstructorParameters<typeof FormComponent>[1]
|
|
42
36
|
) {
|
|
43
37
|
super(def, props)
|
|
44
38
|
|
|
45
|
-
const { name, options
|
|
39
|
+
const { name, options } = def
|
|
46
40
|
|
|
47
41
|
const isRequired = options.required !== false
|
|
48
42
|
const hideOptional = !!options.optionalText
|
|
@@ -126,7 +120,6 @@ export class UkAddressField extends FormComponent {
|
|
|
126
120
|
this.options = options
|
|
127
121
|
this.formSchema = this.collection.formSchema
|
|
128
122
|
this.stateSchema = this.collection.stateSchema
|
|
129
|
-
this.shortDescription = shortDescription
|
|
130
123
|
}
|
|
131
124
|
|
|
132
125
|
getFormValueFromState(state: FormSubmissionState) {
|
|
@@ -174,14 +167,14 @@ export class UkAddressField extends FormComponent {
|
|
|
174
167
|
// When using postcode lookup, the address fields are hidden
|
|
175
168
|
// so we replace any individual validation messages with a single one
|
|
176
169
|
if (this.shouldUsePostcodeLookup() && uniqueErrors?.length) {
|
|
177
|
-
const { name,
|
|
170
|
+
const { name, label } = this
|
|
178
171
|
|
|
179
172
|
return [
|
|
180
173
|
{
|
|
181
174
|
name,
|
|
182
175
|
path: [name],
|
|
183
176
|
href: `#${name}`,
|
|
184
|
-
text: `Enter ${lowerFirst(
|
|
177
|
+
text: `Enter ${lowerFirst(label)}`
|
|
185
178
|
}
|
|
186
179
|
]
|
|
187
180
|
}
|