@defra/forms-engine-plugin 4.15.0 → 4.17.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/.public/stylesheets/application.min.css +1 -1
- package/.public/stylesheets/application.min.css.map +1 -1
- package/.server/client/stylesheets/_prose.scss +19 -0
- package/.server/server/forms/simple-form.yaml +19 -0
- package/.server/server/plugins/engine/components/DatePartsField.js +28 -4
- package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
- package/.server/server/plugins/engine/components/MonthYearField.js +23 -1
- package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
- package/.server/server/plugins/engine/components/NotificationBanner.d.ts +56 -0
- package/.server/server/plugins/engine/components/NotificationBanner.js +28 -0
- package/.server/server/plugins/engine/components/NotificationBanner.js.map +1 -0
- package/.server/server/plugins/engine/components/helpers/components.d.ts +1 -1
- package/.server/server/plugins/engine/components/helpers/components.js +3 -0
- package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
- package/.server/server/plugins/engine/components/index.d.ts +1 -0
- package/.server/server/plugins/engine/components/index.js +1 -0
- package/.server/server/plugins/engine/components/index.js.map +1 -1
- package/.server/server/plugins/engine/views/components/notificationbanner.html +15 -0
- package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
- package/package.json +2 -2
- package/src/client/stylesheets/_prose.scss +19 -0
- package/src/server/forms/simple-form.yaml +19 -0
- package/src/server/plugins/engine/components/DatePartsField.ts +25 -5
- package/src/server/plugins/engine/components/MonthYearField.ts +29 -1
- package/src/server/plugins/engine/components/NotificationBanner.ts +32 -0
- package/src/server/plugins/engine/components/helpers/components.ts +5 -0
- package/src/server/plugins/engine/components/index.ts +1 -0
- package/src/server/plugins/engine/views/components/notificationbanner.html +15 -0
|
@@ -54,3 +54,22 @@
|
|
|
54
54
|
@extend %govuk-section-break--xl;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
.govuk-notification-banner__content {
|
|
59
|
+
.app-prose-scope > :last-child {
|
|
60
|
+
margin-bottom: 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// GOV.UK Frontend does not expose placeholder selectors for these — class selectors are the only option.
|
|
65
|
+
.app-prose-notification-banner-scope {
|
|
66
|
+
p {
|
|
67
|
+
// stylelint-disable-next-line scss/at-extend-no-missing-placeholder
|
|
68
|
+
@extend .govuk-notification-banner__heading;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
a {
|
|
72
|
+
// stylelint-disable-next-line scss/at-extend-no-missing-placeholder
|
|
73
|
+
@extend .govuk-notification-banner__link;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -78,6 +78,25 @@ pages:
|
|
|
78
78
|
id: '00738799-3489-4ab2-a57b-542eecb31bfa'
|
|
79
79
|
next: []
|
|
80
80
|
id: da0fbdb4-a2de-4650-be16-9ba552af135f
|
|
81
|
+
- title: ''
|
|
82
|
+
path: '/notification-demo'
|
|
83
|
+
components:
|
|
84
|
+
- type: NotificationBanner
|
|
85
|
+
title: Important
|
|
86
|
+
name: notificationImportant
|
|
87
|
+
content: 'Contact us if you need [help with your application](https://www.defra.gov.uk).'
|
|
88
|
+
options:
|
|
89
|
+
heading: There may be a delay in processing your application.
|
|
90
|
+
id: ca6b6590-1608-49f4-82f9-9d92e38e66ea
|
|
91
|
+
- type: NotificationBanner
|
|
92
|
+
title: Success
|
|
93
|
+
name: notificationSuccess
|
|
94
|
+
content: 'Your application has been submitted.'
|
|
95
|
+
options:
|
|
96
|
+
type: success
|
|
97
|
+
id: b6960f4b-d771-4956-9c9b-17da5c603062
|
|
98
|
+
next: []
|
|
99
|
+
id: be4b4b86-514c-43bb-8cdc-f9aed6155924
|
|
81
100
|
- id: 449a45f6-4541-4a46-91bd-8b8931b07b50
|
|
82
101
|
title: ''
|
|
83
102
|
path: '/summary'
|
|
@@ -199,6 +199,12 @@ export class DatePartsField extends FormComponent {
|
|
|
199
199
|
}, {
|
|
200
200
|
type: 'dateMax',
|
|
201
201
|
template: messageTemplate.dateMax
|
|
202
|
+
}, {
|
|
203
|
+
type: 'earliestDate',
|
|
204
|
+
template: messageTemplate.dateMin
|
|
205
|
+
}, {
|
|
206
|
+
type: 'latestDate',
|
|
207
|
+
template: messageTemplate.dateMax
|
|
202
208
|
}]
|
|
203
209
|
};
|
|
204
210
|
}
|
|
@@ -230,21 +236,39 @@ export function getValidatorDate(component) {
|
|
|
230
236
|
const dateMin = options.maxDaysInPast || options.maxDaysInPast === 0 ? sub(startOfToday(), {
|
|
231
237
|
days: options.maxDaysInPast
|
|
232
238
|
}) : undefined;
|
|
239
|
+
if (dateMin && date < dateMin) {
|
|
240
|
+
return helpers.error('date.min', {
|
|
241
|
+
...context,
|
|
242
|
+
limit: dateMin
|
|
243
|
+
});
|
|
244
|
+
}
|
|
233
245
|
|
|
234
246
|
// Maximum date from today
|
|
235
247
|
const dateMax = options.maxDaysInFuture || options.maxDaysInFuture === 0 ? add(startOfToday(), {
|
|
236
248
|
days: options.maxDaysInFuture
|
|
237
249
|
}) : undefined;
|
|
238
|
-
if (
|
|
250
|
+
if (dateMax && date > dateMax) {
|
|
251
|
+
return helpers.error('date.max', {
|
|
252
|
+
...context,
|
|
253
|
+
limit: dateMax
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Minimum date from today
|
|
258
|
+
const earliestDate = options.earliestDate ? new Date(options.earliestDate) : undefined;
|
|
259
|
+
if (earliestDate && date < earliestDate) {
|
|
239
260
|
return helpers.error('date.min', {
|
|
240
261
|
...context,
|
|
241
|
-
limit:
|
|
262
|
+
limit: earliestDate
|
|
242
263
|
});
|
|
243
264
|
}
|
|
244
|
-
|
|
265
|
+
|
|
266
|
+
// Maximum date from today
|
|
267
|
+
const latestDate = options.latestDate ? new Date(options.latestDate) : undefined;
|
|
268
|
+
if (latestDate && date > latestDate) {
|
|
245
269
|
return helpers.error('date.max', {
|
|
246
270
|
...context,
|
|
247
|
-
limit:
|
|
271
|
+
limit: latestDate
|
|
248
272
|
});
|
|
249
273
|
}
|
|
250
274
|
return payload;
|
|
@@ -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","maxDaysInFuture","limit"],"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 ]\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 // Maximum date from today\n const dateMax =\n options.maxDaysInFuture || options.maxDaysInFuture === 0\n ? add(startOfToday(), { days: options.maxDaysInFuture })\n : undefined\n\n if (dateMin && date < dateMin) {\n return helpers.error('date.min', { ...context, limit: dateMin })\n }\n\n if (dateMax && date > dateMax) {\n return helpers.error('date.max', { ...context, limit: dateMax })\n }\n\n return payload\n }\n\n return validator\n}\n"],"mappings":"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","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: '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":"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","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentType } from '@defra/forms-model';
|
|
2
|
-
import { format, isValid } from 'date-fns';
|
|
2
|
+
import { format, isValid, parse } from 'date-fns';
|
|
3
3
|
import { ComponentCollection } from "./ComponentCollection.js";
|
|
4
4
|
import { FormComponent, isFormState, isFormValue } from "./FormComponent.js";
|
|
5
5
|
import { NumberField } from "./NumberField.js";
|
|
@@ -205,6 +205,28 @@ export function getValidatorMonthYear(component) {
|
|
|
205
205
|
if (!component.isState(values)) {
|
|
206
206
|
return options.required !== false ? helpers.error('object.required', context) : payload;
|
|
207
207
|
}
|
|
208
|
+
const date = parse(`${values.year}-${values.month}-01`, 'yyyy-MM-dd', new Date());
|
|
209
|
+
if (!isValid(date)) {
|
|
210
|
+
return helpers.error('date.format', context);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Minimum date from today
|
|
214
|
+
const earliestDate = options.earliestMonthYear ? new Date(`${options.earliestMonthYear}-01`) : undefined;
|
|
215
|
+
if (earliestDate && date < earliestDate) {
|
|
216
|
+
return helpers.error('date.min', {
|
|
217
|
+
...context,
|
|
218
|
+
limit: earliestDate
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Maximum date from today
|
|
223
|
+
const latestDate = options.latestMonthYear ? new Date(`${options.latestMonthYear}-01`) : undefined;
|
|
224
|
+
if (latestDate && date > latestDate) {
|
|
225
|
+
return helpers.error('date.max', {
|
|
226
|
+
...context,
|
|
227
|
+
limit: latestDate
|
|
228
|
+
});
|
|
229
|
+
}
|
|
208
230
|
return payload;
|
|
209
231
|
};
|
|
210
232
|
return validator;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MonthYearField.js","names":["ComponentType","format","isValid","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"],"sources":["../../../../../src/server/plugins/engine/components/MonthYearField.ts"],"sourcesContent":["import { ComponentType, type MonthYearFieldComponent } from '@defra/forms-model'\nimport { format, isValid } 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 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: '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":[]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type NotificationBannerComponent } from '@defra/forms-model';
|
|
2
|
+
import { ComponentBase } from '../../../../server/plugins/engine/components/ComponentBase.js';
|
|
3
|
+
export declare class NotificationBanner extends ComponentBase {
|
|
4
|
+
options: NotificationBannerComponent['options'];
|
|
5
|
+
content: NotificationBannerComponent['content'];
|
|
6
|
+
constructor(def: NotificationBannerComponent, props: ConstructorParameters<typeof ComponentBase>[1]);
|
|
7
|
+
getViewModel(): {
|
|
8
|
+
titleHtml: string;
|
|
9
|
+
content: string;
|
|
10
|
+
heading: string | undefined;
|
|
11
|
+
type: "success" | undefined;
|
|
12
|
+
label?: import("./types.js").Label;
|
|
13
|
+
id?: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
value?: import("../types.js").FormValue;
|
|
16
|
+
hint?: {
|
|
17
|
+
id?: string;
|
|
18
|
+
text: string;
|
|
19
|
+
};
|
|
20
|
+
prefix?: import("./types.js").ComponentText;
|
|
21
|
+
suffix?: import("./types.js").ComponentText;
|
|
22
|
+
classes?: string;
|
|
23
|
+
condition?: string;
|
|
24
|
+
errors?: import("../types.js").FormSubmissionError[];
|
|
25
|
+
errorMessage?: {
|
|
26
|
+
text: string;
|
|
27
|
+
};
|
|
28
|
+
summaryHtml?: string;
|
|
29
|
+
html?: string;
|
|
30
|
+
attributes: {
|
|
31
|
+
autocomplete?: string;
|
|
32
|
+
maxlength?: number;
|
|
33
|
+
multiple?: string;
|
|
34
|
+
accept?: string;
|
|
35
|
+
inputmode?: string;
|
|
36
|
+
};
|
|
37
|
+
maxlength?: number;
|
|
38
|
+
maxwords?: number;
|
|
39
|
+
rows?: number;
|
|
40
|
+
items?: import("./types.js").ListItem[] | import("./types.js").DateInputItem[];
|
|
41
|
+
fieldset?: {
|
|
42
|
+
attributes?: string | Record<string, string>;
|
|
43
|
+
legend?: import("./types.js").Label;
|
|
44
|
+
};
|
|
45
|
+
formGroup?: {
|
|
46
|
+
classes?: string;
|
|
47
|
+
attributes?: string | Record<string, string>;
|
|
48
|
+
};
|
|
49
|
+
showFieldsetError?: boolean;
|
|
50
|
+
components?: import("./types.js").ComponentViewModel[];
|
|
51
|
+
upload?: {
|
|
52
|
+
count: number;
|
|
53
|
+
summaryList: import("../types.js").SummaryList;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ComponentBase } from "./ComponentBase.js";
|
|
2
|
+
export class NotificationBanner extends ComponentBase {
|
|
3
|
+
content;
|
|
4
|
+
constructor(def, props) {
|
|
5
|
+
super(def, props);
|
|
6
|
+
const {
|
|
7
|
+
content,
|
|
8
|
+
options
|
|
9
|
+
} = def;
|
|
10
|
+
this.content = content;
|
|
11
|
+
this.options = options;
|
|
12
|
+
}
|
|
13
|
+
getViewModel() {
|
|
14
|
+
const {
|
|
15
|
+
content,
|
|
16
|
+
title,
|
|
17
|
+
viewModel
|
|
18
|
+
} = this;
|
|
19
|
+
return {
|
|
20
|
+
...viewModel,
|
|
21
|
+
titleHtml: title,
|
|
22
|
+
content,
|
|
23
|
+
heading: this.options.heading,
|
|
24
|
+
type: this.options.type
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=NotificationBanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NotificationBanner.js","names":["ComponentBase","NotificationBanner","content","constructor","def","props","options","getViewModel","title","viewModel","titleHtml","heading","type"],"sources":["../../../../../src/server/plugins/engine/components/NotificationBanner.ts"],"sourcesContent":["import { type NotificationBannerComponent } from '@defra/forms-model'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\n\nexport class NotificationBanner extends ComponentBase {\n declare options: NotificationBannerComponent['options']\n content: NotificationBannerComponent['content']\n\n constructor(\n def: NotificationBannerComponent,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { content, options } = def\n\n this.content = content\n this.options = options\n }\n\n getViewModel() {\n const { content, title, viewModel } = this\n\n return {\n ...viewModel,\n titleHtml: title,\n content,\n heading: this.options.heading,\n type: this.options.type\n }\n }\n}\n"],"mappings":"AAEA,SAASA,aAAa;AAEtB,OAAO,MAAMC,kBAAkB,SAASD,aAAa,CAAC;EAEpDE,OAAO;EAEPC,WAAWA,CACTC,GAAgC,EAChCC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEH,OAAO;MAAEI;IAAQ,CAAC,GAAGF,GAAG;IAEhC,IAAI,CAACF,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACI,OAAO,GAAGA,OAAO;EACxB;EAEAC,YAAYA,CAAA,EAAG;IACb,MAAM;MAAEL,OAAO;MAAEM,KAAK;MAAEC;IAAU,CAAC,GAAG,IAAI;IAE1C,OAAO;MACL,GAAGA,SAAS;MACZC,SAAS,EAAEF,KAAK;MAChBN,OAAO;MACPS,OAAO,EAAE,IAAI,CAACL,OAAO,CAACK,OAAO;MAC7BC,IAAI,EAAE,IAAI,CAACN,OAAO,CAACM;IACrB,CAAC;EACH;AACF","ignoreList":[]}
|
|
@@ -5,7 +5,7 @@ import * as Components from '../../../../../server/plugins/engine/components/ind
|
|
|
5
5
|
import { type FormState } from '../../../../../server/plugins/engine/types.js';
|
|
6
6
|
export type Component = InstanceType<(typeof Components)[keyof typeof Components]>;
|
|
7
7
|
export type Field = InstanceType<typeof Components.AutocompleteField | typeof Components.RadiosField | typeof Components.YesNoField | typeof Components.CheckboxesField | typeof Components.DatePartsField | typeof Components.DeclarationField | typeof Components.EastingNorthingField | typeof Components.EmailAddressField | typeof Components.LatLongField | typeof Components.MonthYearField | typeof Components.MultilineTextField | typeof Components.NationalGridFieldNumberField | typeof Components.NumberField | typeof Components.OsGridRefField | typeof Components.SelectField | typeof Components.TelephoneNumberField | typeof Components.TextField | typeof Components.UkAddressField | typeof Components.FileUploadField | typeof Components.HiddenField | typeof Components.PaymentField | typeof Components.GeospatialField>;
|
|
8
|
-
export type Guidance = InstanceType<typeof Components.Details> | InstanceType<typeof Components.Html> | InstanceType<typeof Components.Markdown> | InstanceType<typeof Components.InsetText> | InstanceType<typeof Components.List>;
|
|
8
|
+
export type Guidance = InstanceType<typeof Components.Details> | InstanceType<typeof Components.Html> | InstanceType<typeof Components.Markdown> | InstanceType<typeof Components.InsetText> | InstanceType<typeof Components.List> | InstanceType<typeof Components.NotificationBanner>;
|
|
9
9
|
export type ListField = InstanceType<typeof Components.AutocompleteField | typeof Components.CheckboxesField | typeof Components.RadiosField | typeof Components.SelectField | typeof Components.YesNoField>;
|
|
10
10
|
export declare const designerUrl: string;
|
|
11
11
|
export { markdown } from '../../../../../server/plugins/engine/components/markdownParser.js';
|
|
@@ -65,6 +65,9 @@ export function createComponent(def, options) {
|
|
|
65
65
|
case ComponentType.Markdown:
|
|
66
66
|
component = new Components.Markdown(def, options);
|
|
67
67
|
break;
|
|
68
|
+
case ComponentType.NotificationBanner:
|
|
69
|
+
component = new Components.NotificationBanner(def, options);
|
|
70
|
+
break;
|
|
68
71
|
case ComponentType.MultilineTextField:
|
|
69
72
|
component = new Components.MultilineTextField(def, options);
|
|
70
73
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.js","names":["ComponentType","config","ListFormComponent","escapeMarkdown","Components","markdown","designerUrl","get","hasListFormField","field","type","undefined","isListFieldType","allowedTypes","AutocompleteField","CheckboxesField","RadiosField","SelectField","YesNoField","includes","createComponent","def","options","component","DatePartsField","DeclarationField","Details","EmailAddressField","Html","InsetText","List","Markdown","MultilineTextField","NumberField","TelephoneNumberField","TextField","UkAddressField","MonthYearField","FileUploadField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField","Error","getAnswer","state","format","getAnswerMarkdown","context","getContextValueFromState","toString","parse","async","trim","getDisplayStringFromState","answer","answerEscaped","files","getFormValueFromState","length","map","status","file","form","filename","fileId","join","values","flat","items","filter","value","item","label","text","line","toLowerCase","split","concat","contextValue","features","getDisplayStringFromFormValue"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/components.ts"],"sourcesContent":["import { ComponentType, type ComponentDef } from '@defra/forms-model'\n\nimport { config } from '~/src/config/index.js'\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js'\nimport { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport * as Components from '~/src/server/plugins/engine/components/index.js'\nimport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\nimport { type FormState } from '~/src/server/plugins/engine/types.js'\n\n// All component instances\nexport type Component = InstanceType<\n (typeof Components)[keyof typeof Components]\n>\n\n// Field component instances only\nexport type Field = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.RadiosField\n | typeof Components.YesNoField\n | typeof Components.CheckboxesField\n | typeof Components.DatePartsField\n | typeof Components.DeclarationField\n | typeof Components.EastingNorthingField\n | typeof Components.EmailAddressField\n | typeof Components.LatLongField\n | typeof Components.MonthYearField\n | typeof Components.MultilineTextField\n | typeof Components.NationalGridFieldNumberField\n | typeof Components.NumberField\n | typeof Components.OsGridRefField\n | typeof Components.SelectField\n | typeof Components.TelephoneNumberField\n | typeof Components.TextField\n | typeof Components.UkAddressField\n | typeof Components.FileUploadField\n | typeof Components.HiddenField\n | typeof Components.PaymentField\n | typeof Components.GeospatialField\n>\n\n// Guidance component instances only\nexport type Guidance =\n | InstanceType<typeof Components.Details>\n | InstanceType<typeof Components.Html>\n | InstanceType<typeof Components.Markdown>\n | InstanceType<typeof Components.InsetText>\n | InstanceType<typeof Components.List>\n\n// List component instances only\nexport type ListField = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.CheckboxesField\n | typeof Components.RadiosField\n | typeof Components.SelectField\n | typeof Components.YesNoField\n>\n\nexport const designerUrl = config.get('designerUrl')\n\n// Re-export markdown from its own module to avoid circular dependencies\nexport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\n\n/**\n * Filter known components with lists\n */\nexport function hasListFormField(\n field?: Partial<Component>\n): field is ListFormComponent {\n return !!field && field.type !== undefined && isListFieldType(field.type)\n}\n\nexport function isListFieldType(\n type?: ComponentType\n): type is ListField['type'] {\n const allowedTypes = [\n ComponentType.AutocompleteField,\n ComponentType.CheckboxesField,\n ComponentType.RadiosField,\n ComponentType.SelectField,\n ComponentType.YesNoField\n ]\n\n return !!type && allowedTypes.includes(type)\n}\n\n/**\n * Create field instance for each {@link ComponentDef} type\n */\nexport function createComponent(\n def: ComponentDef,\n options: ConstructorParameters<typeof ComponentBase>[1]\n): Component {\n let component: Component | undefined\n\n switch (def.type) {\n case ComponentType.AutocompleteField:\n component = new Components.AutocompleteField(def, options)\n break\n\n case ComponentType.CheckboxesField:\n component = new Components.CheckboxesField(def, options)\n break\n\n case ComponentType.DatePartsField:\n component = new Components.DatePartsField(def, options)\n break\n\n case ComponentType.DeclarationField:\n component = new Components.DeclarationField(def, options)\n break\n\n case ComponentType.Details:\n component = new Components.Details(def, options)\n break\n\n case ComponentType.EmailAddressField:\n component = new Components.EmailAddressField(def, options)\n break\n\n case ComponentType.Html:\n component = new Components.Html(def, options)\n break\n\n case ComponentType.InsetText:\n component = new Components.InsetText(def, options)\n break\n\n case ComponentType.List:\n component = new Components.List(def, options)\n break\n\n case ComponentType.Markdown:\n component = new Components.Markdown(def, options)\n break\n\n case ComponentType.MultilineTextField:\n component = new Components.MultilineTextField(def, options)\n break\n\n case ComponentType.NumberField:\n component = new Components.NumberField(def, options)\n break\n\n case ComponentType.RadiosField:\n component = new Components.RadiosField(def, options)\n break\n\n case ComponentType.SelectField:\n component = new Components.SelectField(def, options)\n break\n\n case ComponentType.TelephoneNumberField:\n component = new Components.TelephoneNumberField(def, options)\n break\n\n case ComponentType.TextField:\n component = new Components.TextField(def, options)\n break\n\n case ComponentType.UkAddressField:\n component = new Components.UkAddressField(def, options)\n break\n\n case ComponentType.YesNoField:\n component = new Components.YesNoField(def, options)\n break\n\n case ComponentType.MonthYearField:\n component = new Components.MonthYearField(def, options)\n break\n\n case ComponentType.FileUploadField:\n component = new Components.FileUploadField(def, options)\n break\n\n case ComponentType.EastingNorthingField:\n component = new Components.EastingNorthingField(def, options)\n break\n\n case ComponentType.OsGridRefField:\n component = new Components.OsGridRefField(def, options)\n break\n\n case ComponentType.NationalGridFieldNumberField:\n component = new Components.NationalGridFieldNumberField(def, options)\n break\n\n case ComponentType.LatLongField:\n component = new Components.LatLongField(def, options)\n break\n\n case ComponentType.HiddenField:\n component = new Components.HiddenField(def, options)\n break\n\n case ComponentType.PaymentField:\n component = new Components.PaymentField(def, options)\n break\n\n case ComponentType.GeospatialField:\n component = new Components.GeospatialField(def, options)\n break\n }\n\n if (typeof component === 'undefined') {\n throw new Error(`Component type ${def.type} does not exist`)\n }\n\n return component\n}\n\n/**\n * Get formatted answer for a field\n */\nexport function getAnswer(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'data' // Submission data\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n // Use escaped display text for GOV.UK Notify emails\n if (options.format === 'email') {\n return getAnswerMarkdown(field, state, { format: 'email' })\n }\n\n // Use context value for submission data\n if (options.format === 'data') {\n const context = field.getContextValueFromState(state)\n return context?.toString() ?? ''\n }\n\n // Use display HTML for check answers summary (multi line)\n if (\n field instanceof ListFormComponent ||\n field instanceof Components.MultilineTextField ||\n field instanceof Components.UkAddressField ||\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n return markdown\n .parse(getAnswerMarkdown(field, state), { async: false })\n .trim()\n }\n\n // Use display text for check answers summary (single line)\n return field.getDisplayStringFromState(state)\n}\n\n/**\n * Get formatted answer for a field (Markdown only)\n */\nexport function getAnswerMarkdown(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n const answer = field.getDisplayStringFromState(state)\n\n // Use escaped display text\n let answerEscaped = `${escapeMarkdown(answer)}\\n`\n\n if (field instanceof Components.FileUploadField) {\n const files = field.getFormValueFromState(state)\n\n // Skip empty files\n if (!files?.length) {\n return answerEscaped\n }\n\n answerEscaped = `${escapeMarkdown(answer)}:\\n\\n`\n\n // Append bullet points\n answerEscaped += files\n .map(({ status }) => {\n const { file } = status.form\n const filename = escapeMarkdown(file.filename)\n return `* [${filename}](${designerUrl}/file-download/${file.fileId})\\n`\n })\n .join('')\n } else if (field instanceof ListFormComponent) {\n const values = [field.getContextValueFromState(state)].flat()\n const items = field.items.filter(({ value }) => values.includes(value))\n\n // Skip empty values\n if (!items.length) {\n return answerEscaped\n }\n\n answerEscaped = ''\n\n // Append bullet points\n answerEscaped += items\n .map((item) => {\n const label = escapeMarkdown(item.text)\n const value = escapeMarkdown(`(${item.value})`)\n\n let line = label\n\n // Prepend bullet points for checkboxes only\n if (field instanceof Components.CheckboxesField) {\n line = `* ${line}`\n }\n\n // Append raw values in parentheses\n // e.g. `* None of the above (false)`\n return options.format === 'email' &&\n `${item.value}`.toLowerCase() !== item.text.toLowerCase()\n ? `${line} ${value}\\n`\n : `${line}\\n`\n })\n .join('')\n } else if (field instanceof Components.MultilineTextField) {\n // Preserve Multiline text new lines\n answerEscaped = answer\n .split(/(?:\\r?\\n)+/)\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (field instanceof Components.UkAddressField) {\n // Format UK addresses into new lines\n answerEscaped = (field.getContextValueFromState(state) ?? [])\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n const contextValue = field.getContextValueFromState(state)\n answerEscaped = contextValue ? `${contextValue}\\n` : ''\n } else if (field instanceof Components.GeospatialField) {\n const features = field.getFormValueFromState(state)\n const value = field.getDisplayStringFromFormValue(features)\n\n answerEscaped = value ? `${value}\\n` : ''\n }\n\n return answerEscaped\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"components.js","names":["ComponentType","config","ListFormComponent","escapeMarkdown","Components","markdown","designerUrl","get","hasListFormField","field","type","undefined","isListFieldType","allowedTypes","AutocompleteField","CheckboxesField","RadiosField","SelectField","YesNoField","includes","createComponent","def","options","component","DatePartsField","DeclarationField","Details","EmailAddressField","Html","InsetText","List","Markdown","NotificationBanner","MultilineTextField","NumberField","TelephoneNumberField","TextField","UkAddressField","MonthYearField","FileUploadField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField","Error","getAnswer","state","format","getAnswerMarkdown","context","getContextValueFromState","toString","parse","async","trim","getDisplayStringFromState","answer","answerEscaped","files","getFormValueFromState","length","map","status","file","form","filename","fileId","join","values","flat","items","filter","value","item","label","text","line","toLowerCase","split","concat","contextValue","features","getDisplayStringFromFormValue"],"sources":["../../../../../../src/server/plugins/engine/components/helpers/components.ts"],"sourcesContent":["import { ComponentType, type ComponentDef } from '@defra/forms-model'\n\nimport { config } from '~/src/config/index.js'\nimport { type ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { ListFormComponent } from '~/src/server/plugins/engine/components/ListFormComponent.js'\nimport { escapeMarkdown } from '~/src/server/plugins/engine/components/helpers/index.js'\nimport * as Components from '~/src/server/plugins/engine/components/index.js'\nimport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\nimport { type FormState } from '~/src/server/plugins/engine/types.js'\n\n// All component instances\nexport type Component = InstanceType<\n (typeof Components)[keyof typeof Components]\n>\n\n// Field component instances only\nexport type Field = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.RadiosField\n | typeof Components.YesNoField\n | typeof Components.CheckboxesField\n | typeof Components.DatePartsField\n | typeof Components.DeclarationField\n | typeof Components.EastingNorthingField\n | typeof Components.EmailAddressField\n | typeof Components.LatLongField\n | typeof Components.MonthYearField\n | typeof Components.MultilineTextField\n | typeof Components.NationalGridFieldNumberField\n | typeof Components.NumberField\n | typeof Components.OsGridRefField\n | typeof Components.SelectField\n | typeof Components.TelephoneNumberField\n | typeof Components.TextField\n | typeof Components.UkAddressField\n | typeof Components.FileUploadField\n | typeof Components.HiddenField\n | typeof Components.PaymentField\n | typeof Components.GeospatialField\n>\n\n// Guidance component instances only\nexport type Guidance =\n | InstanceType<typeof Components.Details>\n | InstanceType<typeof Components.Html>\n | InstanceType<typeof Components.Markdown>\n | InstanceType<typeof Components.InsetText>\n | InstanceType<typeof Components.List>\n | InstanceType<typeof Components.NotificationBanner>\n\n// List component instances only\nexport type ListField = InstanceType<\n | typeof Components.AutocompleteField\n | typeof Components.CheckboxesField\n | typeof Components.RadiosField\n | typeof Components.SelectField\n | typeof Components.YesNoField\n>\n\nexport const designerUrl = config.get('designerUrl')\n\n// Re-export markdown from its own module to avoid circular dependencies\nexport { markdown } from '~/src/server/plugins/engine/components/markdownParser.js'\n\n/**\n * Filter known components with lists\n */\nexport function hasListFormField(\n field?: Partial<Component>\n): field is ListFormComponent {\n return !!field && field.type !== undefined && isListFieldType(field.type)\n}\n\nexport function isListFieldType(\n type?: ComponentType\n): type is ListField['type'] {\n const allowedTypes = [\n ComponentType.AutocompleteField,\n ComponentType.CheckboxesField,\n ComponentType.RadiosField,\n ComponentType.SelectField,\n ComponentType.YesNoField\n ]\n\n return !!type && allowedTypes.includes(type)\n}\n\n/**\n * Create field instance for each {@link ComponentDef} type\n */\nexport function createComponent(\n def: ComponentDef,\n options: ConstructorParameters<typeof ComponentBase>[1]\n): Component {\n let component: Component | undefined\n\n switch (def.type) {\n case ComponentType.AutocompleteField:\n component = new Components.AutocompleteField(def, options)\n break\n\n case ComponentType.CheckboxesField:\n component = new Components.CheckboxesField(def, options)\n break\n\n case ComponentType.DatePartsField:\n component = new Components.DatePartsField(def, options)\n break\n\n case ComponentType.DeclarationField:\n component = new Components.DeclarationField(def, options)\n break\n\n case ComponentType.Details:\n component = new Components.Details(def, options)\n break\n\n case ComponentType.EmailAddressField:\n component = new Components.EmailAddressField(def, options)\n break\n\n case ComponentType.Html:\n component = new Components.Html(def, options)\n break\n\n case ComponentType.InsetText:\n component = new Components.InsetText(def, options)\n break\n\n case ComponentType.List:\n component = new Components.List(def, options)\n break\n\n case ComponentType.Markdown:\n component = new Components.Markdown(def, options)\n break\n\n case ComponentType.NotificationBanner:\n component = new Components.NotificationBanner(def, options)\n break\n\n case ComponentType.MultilineTextField:\n component = new Components.MultilineTextField(def, options)\n break\n\n case ComponentType.NumberField:\n component = new Components.NumberField(def, options)\n break\n\n case ComponentType.RadiosField:\n component = new Components.RadiosField(def, options)\n break\n\n case ComponentType.SelectField:\n component = new Components.SelectField(def, options)\n break\n\n case ComponentType.TelephoneNumberField:\n component = new Components.TelephoneNumberField(def, options)\n break\n\n case ComponentType.TextField:\n component = new Components.TextField(def, options)\n break\n\n case ComponentType.UkAddressField:\n component = new Components.UkAddressField(def, options)\n break\n\n case ComponentType.YesNoField:\n component = new Components.YesNoField(def, options)\n break\n\n case ComponentType.MonthYearField:\n component = new Components.MonthYearField(def, options)\n break\n\n case ComponentType.FileUploadField:\n component = new Components.FileUploadField(def, options)\n break\n\n case ComponentType.EastingNorthingField:\n component = new Components.EastingNorthingField(def, options)\n break\n\n case ComponentType.OsGridRefField:\n component = new Components.OsGridRefField(def, options)\n break\n\n case ComponentType.NationalGridFieldNumberField:\n component = new Components.NationalGridFieldNumberField(def, options)\n break\n\n case ComponentType.LatLongField:\n component = new Components.LatLongField(def, options)\n break\n\n case ComponentType.HiddenField:\n component = new Components.HiddenField(def, options)\n break\n\n case ComponentType.PaymentField:\n component = new Components.PaymentField(def, options)\n break\n\n case ComponentType.GeospatialField:\n component = new Components.GeospatialField(def, options)\n break\n }\n\n if (typeof component === 'undefined') {\n throw new Error(`Component type ${def.type} does not exist`)\n }\n\n return component\n}\n\n/**\n * Get formatted answer for a field\n */\nexport function getAnswer(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'data' // Submission data\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n // Use escaped display text for GOV.UK Notify emails\n if (options.format === 'email') {\n return getAnswerMarkdown(field, state, { format: 'email' })\n }\n\n // Use context value for submission data\n if (options.format === 'data') {\n const context = field.getContextValueFromState(state)\n return context?.toString() ?? ''\n }\n\n // Use display HTML for check answers summary (multi line)\n if (\n field instanceof ListFormComponent ||\n field instanceof Components.MultilineTextField ||\n field instanceof Components.UkAddressField ||\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n return markdown\n .parse(getAnswerMarkdown(field, state), { async: false })\n .trim()\n }\n\n // Use display text for check answers summary (single line)\n return field.getDisplayStringFromState(state)\n}\n\n/**\n * Get formatted answer for a field (Markdown only)\n */\nexport function getAnswerMarkdown(\n field: Field,\n state: FormState,\n options: {\n format:\n | 'email' // GOV.UK Notify emails\n | 'summary' // Check answers summary\n } = { format: 'summary' }\n) {\n const answer = field.getDisplayStringFromState(state)\n\n // Use escaped display text\n let answerEscaped = `${escapeMarkdown(answer)}\\n`\n\n if (field instanceof Components.FileUploadField) {\n const files = field.getFormValueFromState(state)\n\n // Skip empty files\n if (!files?.length) {\n return answerEscaped\n }\n\n answerEscaped = `${escapeMarkdown(answer)}:\\n\\n`\n\n // Append bullet points\n answerEscaped += files\n .map(({ status }) => {\n const { file } = status.form\n const filename = escapeMarkdown(file.filename)\n return `* [${filename}](${designerUrl}/file-download/${file.fileId})\\n`\n })\n .join('')\n } else if (field instanceof ListFormComponent) {\n const values = [field.getContextValueFromState(state)].flat()\n const items = field.items.filter(({ value }) => values.includes(value))\n\n // Skip empty values\n if (!items.length) {\n return answerEscaped\n }\n\n answerEscaped = ''\n\n // Append bullet points\n answerEscaped += items\n .map((item) => {\n const label = escapeMarkdown(item.text)\n const value = escapeMarkdown(`(${item.value})`)\n\n let line = label\n\n // Prepend bullet points for checkboxes only\n if (field instanceof Components.CheckboxesField) {\n line = `* ${line}`\n }\n\n // Append raw values in parentheses\n // e.g. `* None of the above (false)`\n return options.format === 'email' &&\n `${item.value}`.toLowerCase() !== item.text.toLowerCase()\n ? `${line} ${value}\\n`\n : `${line}\\n`\n })\n .join('')\n } else if (field instanceof Components.MultilineTextField) {\n // Preserve Multiline text new lines\n answerEscaped = answer\n .split(/(?:\\r?\\n)+/)\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (field instanceof Components.UkAddressField) {\n // Format UK addresses into new lines\n answerEscaped = (field.getContextValueFromState(state) ?? [])\n .map(escapeMarkdown)\n .join('\\n')\n .concat('\\n')\n } else if (\n field instanceof Components.EastingNorthingField ||\n field instanceof Components.LatLongField\n ) {\n const contextValue = field.getContextValueFromState(state)\n answerEscaped = contextValue ? `${contextValue}\\n` : ''\n } else if (field instanceof Components.GeospatialField) {\n const features = field.getFormValueFromState(state)\n const value = field.getDisplayStringFromFormValue(features)\n\n answerEscaped = value ? `${value}\\n` : ''\n }\n\n return answerEscaped\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -14,6 +14,7 @@ export { Html } from '../../../../server/plugins/engine/components/Html.js';
|
|
|
14
14
|
export { InsetText } from '../../../../server/plugins/engine/components/InsetText.js';
|
|
15
15
|
export { List } from '../../../../server/plugins/engine/components/List.js';
|
|
16
16
|
export { Markdown } from '../../../../server/plugins/engine/components/Markdown.js';
|
|
17
|
+
export { NotificationBanner } from '../../../../server/plugins/engine/components/NotificationBanner.js';
|
|
17
18
|
export { MonthYearField } from '../../../../server/plugins/engine/components/MonthYearField.js';
|
|
18
19
|
export { MultilineTextField } from '../../../../server/plugins/engine/components/MultilineTextField.js';
|
|
19
20
|
export { NumberField } from '../../../../server/plugins/engine/components/NumberField.js';
|
|
@@ -15,6 +15,7 @@ export { Html } from "./Html.js";
|
|
|
15
15
|
export { InsetText } from "./InsetText.js";
|
|
16
16
|
export { List } from "./List.js";
|
|
17
17
|
export { Markdown } from "./Markdown.js";
|
|
18
|
+
export { NotificationBanner } from "./NotificationBanner.js";
|
|
18
19
|
export { MonthYearField } from "./MonthYearField.js";
|
|
19
20
|
export { MultilineTextField } from "./MultilineTextField.js";
|
|
20
21
|
export { NumberField } from "./NumberField.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["AutocompleteField","CheckboxesField","DatePartsField","DeclarationField","Details","EmailAddressField","FileUploadField","Html","InsetText","List","Markdown","MonthYearField","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField"],"sources":["../../../../../src/server/plugins/engine/components/index.ts"],"sourcesContent":["/**\n * IMPORTANT: Exported Components must follow the naming convention implemented in {@link @defra/forms-model#ComponentType}\n * In the Form JSON, components have a type property which is the name of the components, e.g. DatePartsField.\n * Components are loaded in the ComponentsCollection constructor.\n */\n\nexport { AutocompleteField } from '~/src/server/plugins/engine/components/AutocompleteField.js'\nexport { CheckboxesField } from '~/src/server/plugins/engine/components/CheckboxesField.js'\nexport { DatePartsField } from '~/src/server/plugins/engine/components/DatePartsField.js'\nexport { DeclarationField } from '~/src/server/plugins/engine/components/DeclarationField.js'\nexport { Details } from '~/src/server/plugins/engine/components/Details.js'\nexport { EmailAddressField } from '~/src/server/plugins/engine/components/EmailAddressField.js'\nexport { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js'\nexport { Html } from '~/src/server/plugins/engine/components/Html.js'\nexport { InsetText } from '~/src/server/plugins/engine/components/InsetText.js'\nexport { List } from '~/src/server/plugins/engine/components/List.js'\nexport { Markdown } from '~/src/server/plugins/engine/components/Markdown.js'\nexport { MonthYearField } from '~/src/server/plugins/engine/components/MonthYearField.js'\nexport { MultilineTextField } from '~/src/server/plugins/engine/components/MultilineTextField.js'\nexport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nexport { RadiosField } from '~/src/server/plugins/engine/components/RadiosField.js'\nexport { SelectField } from '~/src/server/plugins/engine/components/SelectField.js'\nexport { TelephoneNumberField } from '~/src/server/plugins/engine/components/TelephoneNumberField.js'\nexport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nexport { UkAddressField } from '~/src/server/plugins/engine/components/UkAddressField.js'\nexport { YesNoField } from '~/src/server/plugins/engine/components/YesNoField.js'\nexport { EastingNorthingField } from '~/src/server/plugins/engine/components/EastingNorthingField.js'\nexport { OsGridRefField } from '~/src/server/plugins/engine/components/OsGridRefField.js'\nexport { NationalGridFieldNumberField } from '~/src/server/plugins/engine/components/NationalGridFieldNumberField.js'\nexport { LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js'\nexport { HiddenField } from '~/src/server/plugins/engine/components/HiddenField.js'\nexport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nexport { GeospatialField } from '~/src/server/plugins/engine/components/GeospatialField.js'\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,cAAc;AACvB,SAASC,gBAAgB;AACzB,SAASC,OAAO;AAChB,SAASC,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,IAAI;AACb,SAASC,SAAS;AAClB,SAASC,IAAI;AACb,SAASC,QAAQ;AACjB,SAASC,cAAc;AACvB,SAASC,kBAAkB;AAC3B,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,oBAAoB;AAC7B,SAASC,SAAS;AAClB,SAASC,cAAc;AACvB,SAASC,UAAU;AACnB,SAASC,oBAAoB;AAC7B,SAASC,cAAc;AACvB,SAASC,4BAA4B;AACrC,SAASC,YAAY;AACrB,SAASC,WAAW;AACpB,SAASC,YAAY;AACrB,SAASC,eAAe","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["AutocompleteField","CheckboxesField","DatePartsField","DeclarationField","Details","EmailAddressField","FileUploadField","Html","InsetText","List","Markdown","NotificationBanner","MonthYearField","MultilineTextField","NumberField","RadiosField","SelectField","TelephoneNumberField","TextField","UkAddressField","YesNoField","EastingNorthingField","OsGridRefField","NationalGridFieldNumberField","LatLongField","HiddenField","PaymentField","GeospatialField"],"sources":["../../../../../src/server/plugins/engine/components/index.ts"],"sourcesContent":["/**\n * IMPORTANT: Exported Components must follow the naming convention implemented in {@link @defra/forms-model#ComponentType}\n * In the Form JSON, components have a type property which is the name of the components, e.g. DatePartsField.\n * Components are loaded in the ComponentsCollection constructor.\n */\n\nexport { AutocompleteField } from '~/src/server/plugins/engine/components/AutocompleteField.js'\nexport { CheckboxesField } from '~/src/server/plugins/engine/components/CheckboxesField.js'\nexport { DatePartsField } from '~/src/server/plugins/engine/components/DatePartsField.js'\nexport { DeclarationField } from '~/src/server/plugins/engine/components/DeclarationField.js'\nexport { Details } from '~/src/server/plugins/engine/components/Details.js'\nexport { EmailAddressField } from '~/src/server/plugins/engine/components/EmailAddressField.js'\nexport { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js'\nexport { Html } from '~/src/server/plugins/engine/components/Html.js'\nexport { InsetText } from '~/src/server/plugins/engine/components/InsetText.js'\nexport { List } from '~/src/server/plugins/engine/components/List.js'\nexport { Markdown } from '~/src/server/plugins/engine/components/Markdown.js'\nexport { NotificationBanner } from '~/src/server/plugins/engine/components/NotificationBanner.js'\nexport { MonthYearField } from '~/src/server/plugins/engine/components/MonthYearField.js'\nexport { MultilineTextField } from '~/src/server/plugins/engine/components/MultilineTextField.js'\nexport { NumberField } from '~/src/server/plugins/engine/components/NumberField.js'\nexport { RadiosField } from '~/src/server/plugins/engine/components/RadiosField.js'\nexport { SelectField } from '~/src/server/plugins/engine/components/SelectField.js'\nexport { TelephoneNumberField } from '~/src/server/plugins/engine/components/TelephoneNumberField.js'\nexport { TextField } from '~/src/server/plugins/engine/components/TextField.js'\nexport { UkAddressField } from '~/src/server/plugins/engine/components/UkAddressField.js'\nexport { YesNoField } from '~/src/server/plugins/engine/components/YesNoField.js'\nexport { EastingNorthingField } from '~/src/server/plugins/engine/components/EastingNorthingField.js'\nexport { OsGridRefField } from '~/src/server/plugins/engine/components/OsGridRefField.js'\nexport { NationalGridFieldNumberField } from '~/src/server/plugins/engine/components/NationalGridFieldNumberField.js'\nexport { LatLongField } from '~/src/server/plugins/engine/components/LatLongField.js'\nexport { HiddenField } from '~/src/server/plugins/engine/components/HiddenField.js'\nexport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nexport { GeospatialField } from '~/src/server/plugins/engine/components/GeospatialField.js'\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,cAAc;AACvB,SAASC,gBAAgB;AACzB,SAASC,OAAO;AAChB,SAASC,iBAAiB;AAC1B,SAASC,eAAe;AACxB,SAASC,IAAI;AACb,SAASC,SAAS;AAClB,SAASC,IAAI;AACb,SAASC,QAAQ;AACjB,SAASC,kBAAkB;AAC3B,SAASC,cAAc;AACvB,SAASC,kBAAkB;AAC3B,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,WAAW;AACpB,SAASC,oBAAoB;AAC7B,SAASC,SAAS;AAClB,SAASC,cAAc;AACvB,SAASC,UAAU;AACnB,SAASC,oBAAoB;AAC7B,SAASC,cAAc;AACvB,SAASC,4BAA4B;AACrC,SAASC,YAAY;AACrB,SAASC,WAAW;AACpB,SAASC,YAAY;AACrB,SAASC,eAAe","ignoreList":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{% from "govuk/components/notification-banner/macro.njk" import govukNotificationBanner %}
|
|
2
|
+
|
|
3
|
+
{% macro NotificationBanner(component) %}
|
|
4
|
+
{%- set bannerHtml -%}
|
|
5
|
+
{%- if component.model.heading -%}
|
|
6
|
+
<div class="app-prose-notification-banner-scope">{{ component.model.heading | markdown | safe }}</div>
|
|
7
|
+
{%- endif -%}
|
|
8
|
+
<div class="app-prose-scope">{{ component.model.content | markdown | safe }}</div>
|
|
9
|
+
{%- endset -%}
|
|
10
|
+
{{ govukNotificationBanner({
|
|
11
|
+
titleHtml: component.model.titleHtml,
|
|
12
|
+
html: bannerHtml,
|
|
13
|
+
type: component.model.type
|
|
14
|
+
}) }}
|
|
15
|
+
{% endmacro %}
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* @this {NunjucksContext}
|
|
4
4
|
* @param {string} name - The name of the component
|
|
5
5
|
*/
|
|
6
|
-
export function field(this: NunjucksContext, name: string): import("../../engine/components/TextField.js").TextField | import("../../engine/components/SelectField.js").SelectField | import("../../engine/components/RadiosField.js").RadiosField | import("../../engine/components/YesNoField.js").YesNoField | import("../../engine/components/CheckboxesField.js").CheckboxesField | import("../../engine/components/DatePartsField.js").DatePartsField | import("../../engine/components/DeclarationField.js").DeclarationField | import("../../engine/components/EastingNorthingField.js").EastingNorthingField | import("../../engine/components/EmailAddressField.js").EmailAddressField | import("../../engine/components/LatLongField.js").LatLongField | import("../../engine/components/MonthYearField.js").MonthYearField | import("../../engine/components/MultilineTextField.js").MultilineTextField | import("../../engine/components/NationalGridFieldNumberField.js").NationalGridFieldNumberField | import("../../engine/components/NumberField.js").NumberField | import("../../engine/components/OsGridRefField.js").OsGridRefField | import("../../engine/components/TelephoneNumberField.js").TelephoneNumberField | import("../../engine/components/UkAddressField.js").UkAddressField | import("../../engine/components/FileUploadField.js").FileUploadField | import("../../engine/components/HiddenField.js").HiddenField | import("../../engine/components/PaymentField.js").PaymentField | import("../../engine/components/GeospatialField.js").GeospatialField | import("../../engine/components/Details.js").Details | import("../../engine/components/Html.js").Html | import("../../engine/components/InsetText.js").InsetText | import("../../engine/components/List.js").List | import("../../engine/components/Markdown.js").Markdown | undefined;
|
|
6
|
+
export function field(this: NunjucksContext, name: string): import("../../engine/components/TextField.js").TextField | import("../../engine/components/SelectField.js").SelectField | import("../../engine/components/RadiosField.js").RadiosField | import("../../engine/components/YesNoField.js").YesNoField | import("../../engine/components/CheckboxesField.js").CheckboxesField | import("../../engine/components/DatePartsField.js").DatePartsField | import("../../engine/components/DeclarationField.js").DeclarationField | import("../../engine/components/EastingNorthingField.js").EastingNorthingField | import("../../engine/components/EmailAddressField.js").EmailAddressField | import("../../engine/components/LatLongField.js").LatLongField | import("../../engine/components/MonthYearField.js").MonthYearField | import("../../engine/components/MultilineTextField.js").MultilineTextField | import("../../engine/components/NationalGridFieldNumberField.js").NationalGridFieldNumberField | import("../../engine/components/NumberField.js").NumberField | import("../../engine/components/OsGridRefField.js").OsGridRefField | import("../../engine/components/TelephoneNumberField.js").TelephoneNumberField | import("../../engine/components/UkAddressField.js").UkAddressField | import("../../engine/components/FileUploadField.js").FileUploadField | import("../../engine/components/HiddenField.js").HiddenField | import("../../engine/components/PaymentField.js").PaymentField | import("../../engine/components/GeospatialField.js").GeospatialField | import("../../engine/components/Details.js").Details | import("../../engine/components/Html.js").Html | import("../../engine/components/InsetText.js").InsetText | import("../../engine/components/List.js").List | import("../../engine/components/Markdown.js").Markdown | import("../../engine/components/NotificationBanner.js").NotificationBanner | undefined;
|
|
7
7
|
import type { NunjucksContext } from '../../../../server/plugins/nunjucks/types.js';
|