@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra/forms-engine-plugin",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.17.0",
|
|
4
4
|
"description": "Defra forms engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
},
|
|
88
88
|
"license": "SEE LICENSE IN LICENSE",
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"@defra/forms-model": "^3.0.
|
|
90
|
+
"@defra/forms-model": "^3.0.678",
|
|
91
91
|
"@defra/hapi-tracing": "^1.29.0",
|
|
92
92
|
"@defra/interactive-map": "^0.0.22-alpha",
|
|
93
93
|
"@elastic/ecs-pino-format": "^1.5.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'
|
|
@@ -229,7 +229,9 @@ export class DatePartsField extends FormComponent {
|
|
|
229
229
|
],
|
|
230
230
|
advancedSettingsErrors: [
|
|
231
231
|
{ type: 'dateMin', template: messageTemplate.dateMin },
|
|
232
|
-
{ type: 'dateMax', template: messageTemplate.dateMax }
|
|
232
|
+
{ type: 'dateMax', template: messageTemplate.dateMax },
|
|
233
|
+
{ type: 'earliestDate', template: messageTemplate.dateMin },
|
|
234
|
+
{ type: 'latestDate', template: messageTemplate.dateMax }
|
|
233
235
|
]
|
|
234
236
|
}
|
|
235
237
|
}
|
|
@@ -281,20 +283,38 @@ export function getValidatorDate(component: DatePartsField) {
|
|
|
281
283
|
? sub(startOfToday(), { days: options.maxDaysInPast })
|
|
282
284
|
: undefined
|
|
283
285
|
|
|
286
|
+
if (dateMin && date < dateMin) {
|
|
287
|
+
return helpers.error('date.min', { ...context, limit: dateMin })
|
|
288
|
+
}
|
|
289
|
+
|
|
284
290
|
// Maximum date from today
|
|
285
291
|
const dateMax =
|
|
286
292
|
options.maxDaysInFuture || options.maxDaysInFuture === 0
|
|
287
293
|
? add(startOfToday(), { days: options.maxDaysInFuture })
|
|
288
294
|
: undefined
|
|
289
295
|
|
|
290
|
-
if (dateMin && date < dateMin) {
|
|
291
|
-
return helpers.error('date.min', { ...context, limit: dateMin })
|
|
292
|
-
}
|
|
293
|
-
|
|
294
296
|
if (dateMax && date > dateMax) {
|
|
295
297
|
return helpers.error('date.max', { ...context, limit: dateMax })
|
|
296
298
|
}
|
|
297
299
|
|
|
300
|
+
// Minimum date from today
|
|
301
|
+
const earliestDate = options.earliestDate
|
|
302
|
+
? new Date(options.earliestDate)
|
|
303
|
+
: undefined
|
|
304
|
+
|
|
305
|
+
if (earliestDate && date < earliestDate) {
|
|
306
|
+
return helpers.error('date.min', { ...context, limit: earliestDate })
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Maximum date from today
|
|
310
|
+
const latestDate = options.latestDate
|
|
311
|
+
? new Date(options.latestDate)
|
|
312
|
+
: undefined
|
|
313
|
+
|
|
314
|
+
if (latestDate && date > latestDate) {
|
|
315
|
+
return helpers.error('date.max', { ...context, limit: latestDate })
|
|
316
|
+
}
|
|
317
|
+
|
|
298
318
|
return payload
|
|
299
319
|
}
|
|
300
320
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentType, type MonthYearFieldComponent } from '@defra/forms-model'
|
|
2
|
-
import { format, isValid } from 'date-fns'
|
|
2
|
+
import { format, isValid, parse } from 'date-fns'
|
|
3
3
|
import {
|
|
4
4
|
type Context,
|
|
5
5
|
type CustomValidator,
|
|
@@ -259,6 +259,34 @@ export function getValidatorMonthYear(component: MonthYearField) {
|
|
|
259
259
|
: payload
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
const date = parse(
|
|
263
|
+
`${values.year}-${values.month}-01`,
|
|
264
|
+
'yyyy-MM-dd',
|
|
265
|
+
new Date()
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
if (!isValid(date)) {
|
|
269
|
+
return helpers.error('date.format', context)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Minimum date from today
|
|
273
|
+
const earliestDate = options.earliestMonthYear
|
|
274
|
+
? new Date(`${options.earliestMonthYear}-01`)
|
|
275
|
+
: undefined
|
|
276
|
+
|
|
277
|
+
if (earliestDate && date < earliestDate) {
|
|
278
|
+
return helpers.error('date.min', { ...context, limit: earliestDate })
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Maximum date from today
|
|
282
|
+
const latestDate = options.latestMonthYear
|
|
283
|
+
? new Date(`${options.latestMonthYear}-01`)
|
|
284
|
+
: undefined
|
|
285
|
+
|
|
286
|
+
if (latestDate && date > latestDate) {
|
|
287
|
+
return helpers.error('date.max', { ...context, limit: latestDate })
|
|
288
|
+
}
|
|
289
|
+
|
|
262
290
|
return payload
|
|
263
291
|
}
|
|
264
292
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type NotificationBannerComponent } from '@defra/forms-model'
|
|
2
|
+
|
|
3
|
+
import { ComponentBase } from './ComponentBase.js'
|
|
4
|
+
|
|
5
|
+
export class NotificationBanner extends ComponentBase {
|
|
6
|
+
declare options: NotificationBannerComponent['options']
|
|
7
|
+
content: NotificationBannerComponent['content']
|
|
8
|
+
|
|
9
|
+
constructor(
|
|
10
|
+
def: NotificationBannerComponent,
|
|
11
|
+
props: ConstructorParameters<typeof ComponentBase>[1]
|
|
12
|
+
) {
|
|
13
|
+
super(def, props)
|
|
14
|
+
|
|
15
|
+
const { content, options } = def
|
|
16
|
+
|
|
17
|
+
this.content = content
|
|
18
|
+
this.options = options
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
getViewModel() {
|
|
22
|
+
const { content, title, viewModel } = this
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
...viewModel,
|
|
26
|
+
titleHtml: title,
|
|
27
|
+
content,
|
|
28
|
+
heading: this.options.heading,
|
|
29
|
+
type: this.options.type
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -46,6 +46,7 @@ export type Guidance =
|
|
|
46
46
|
| InstanceType<typeof Components.Markdown>
|
|
47
47
|
| InstanceType<typeof Components.InsetText>
|
|
48
48
|
| InstanceType<typeof Components.List>
|
|
49
|
+
| InstanceType<typeof Components.NotificationBanner>
|
|
49
50
|
|
|
50
51
|
// List component instances only
|
|
51
52
|
export type ListField = InstanceType<
|
|
@@ -134,6 +135,10 @@ export function createComponent(
|
|
|
134
135
|
component = new Components.Markdown(def, options)
|
|
135
136
|
break
|
|
136
137
|
|
|
138
|
+
case ComponentType.NotificationBanner:
|
|
139
|
+
component = new Components.NotificationBanner(def, options)
|
|
140
|
+
break
|
|
141
|
+
|
|
137
142
|
case ComponentType.MultilineTextField:
|
|
138
143
|
component = new Components.MultilineTextField(def, options)
|
|
139
144
|
break
|
|
@@ -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'
|
|
@@ -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 %}
|