@defra/forms-model 3.0.502 → 3.0.503
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/dist/module/__stubs__/pages.js +14 -1
- package/dist/module/__stubs__/pages.js.map +1 -1
- package/dist/module/form/form-editor/preview/controller/guidance-page-controller.js +58 -0
- package/dist/module/form/form-editor/preview/controller/guidance-page-controller.js.map +1 -0
- package/dist/module/form/form-editor/preview/controller/page-controller-base.js +363 -0
- package/dist/module/form/form-editor/preview/controller/page-controller-base.js.map +1 -0
- package/dist/module/form/form-editor/preview/controller/page-controller.js +26 -265
- package/dist/module/form/form-editor/preview/controller/page-controller.js.map +1 -1
- package/dist/module/form/form-editor/preview/index.js +2 -0
- package/dist/module/form/form-editor/preview/index.js.map +1 -1
- package/dist/module/form/form-editor/preview/types.js.map +1 -1
- package/dist/module/pages/helpers.js +2 -1
- package/dist/module/pages/helpers.js.map +1 -1
- package/dist/types/__stubs__/pages.d.ts +14 -0
- package/dist/types/__stubs__/pages.d.ts.map +1 -1
- package/dist/types/form/form-editor/preview/controller/guidance-page-controller.d.ts +10 -0
- package/dist/types/form/form-editor/preview/controller/guidance-page-controller.d.ts.map +1 -0
- package/dist/types/form/form-editor/preview/controller/page-controller-base.d.ts +198 -0
- package/dist/types/form/form-editor/preview/controller/page-controller-base.d.ts.map +1 -0
- package/dist/types/form/form-editor/preview/controller/page-controller.d.ts +3 -150
- package/dist/types/form/form-editor/preview/controller/page-controller.d.ts.map +1 -1
- package/dist/types/form/form-editor/preview/index.d.ts +2 -0
- package/dist/types/form/form-editor/preview/types.d.ts +3 -1
- package/dist/types/form/form-editor/preview/types.d.ts.map +1 -1
- package/dist/types/pages/helpers.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__stubs__/pages.ts +20 -1
- package/src/form/form-editor/preview/controller/guidance-page-controller.js +64 -0
- package/src/form/form-editor/preview/controller/page-controller-base.js +388 -0
- package/src/form/form-editor/preview/controller/page-controller.js +28 -288
- package/src/form/form-editor/preview/index.js +2 -0
- package/src/form/form-editor/preview/types.ts +4 -1
- package/src/pages/helpers.ts +2 -1
@@ -0,0 +1,388 @@
|
|
1
|
+
import { ComponentType } from '~/src/components/enums.js'
|
2
|
+
import { HIGHLIGHT_CLASS } from '~/src/form/form-editor/preview/constants.js'
|
3
|
+
import { ContentElements } from '~/src/form/form-editor/preview/content.js'
|
4
|
+
import { Markdown } from '~/src/form/form-editor/preview/markdown.js'
|
5
|
+
import { hasComponents, hasRepeater } from '~/src/pages/helpers.js'
|
6
|
+
|
7
|
+
/**
|
8
|
+
* @type {QuestionRenderer}
|
9
|
+
*/
|
10
|
+
const questionRenderer = {
|
11
|
+
/**
|
12
|
+
* @param {string} _questionTemplate
|
13
|
+
* @param {QuestionBaseModel} _questionBaseModel
|
14
|
+
*/
|
15
|
+
render(_questionTemplate, _questionBaseModel) {
|
16
|
+
//
|
17
|
+
}
|
18
|
+
}
|
19
|
+
/**
|
20
|
+
* Enum for Highlight classes
|
21
|
+
* @readonly
|
22
|
+
* @enum {string}
|
23
|
+
*/
|
24
|
+
const HighlightClass = {
|
25
|
+
TITLE: 'title',
|
26
|
+
GUIDANCE: 'guidance',
|
27
|
+
REPEATER: 'repeater'
|
28
|
+
}
|
29
|
+
|
30
|
+
/**
|
31
|
+
* @implements {PageOverviewElements}
|
32
|
+
*/
|
33
|
+
export class PagePreviewElements {
|
34
|
+
/**
|
35
|
+
* @type {Page | { title: string }}
|
36
|
+
* @private
|
37
|
+
*/
|
38
|
+
_page = {
|
39
|
+
title: ''
|
40
|
+
}
|
41
|
+
|
42
|
+
/**
|
43
|
+
* @param {Page|undefined} page
|
44
|
+
*/
|
45
|
+
constructor(page) {
|
46
|
+
if (page !== undefined) {
|
47
|
+
this._page = page
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
get heading() {
|
52
|
+
return this._page.title
|
53
|
+
}
|
54
|
+
|
55
|
+
get guidance() {
|
56
|
+
if (!hasComponents(this._page) || !this._page.components.length) {
|
57
|
+
return ''
|
58
|
+
}
|
59
|
+
|
60
|
+
const [possibleGuidanceComponent] = this._page.components
|
61
|
+
|
62
|
+
return possibleGuidanceComponent.type === ComponentType.Markdown
|
63
|
+
? possibleGuidanceComponent.content
|
64
|
+
: ''
|
65
|
+
}
|
66
|
+
|
67
|
+
get addHeading() {
|
68
|
+
return this._page.title.length > 0
|
69
|
+
}
|
70
|
+
|
71
|
+
get repeatQuestion() {
|
72
|
+
if (hasRepeater(this._page)) {
|
73
|
+
return this._page.repeat.options.title
|
74
|
+
}
|
75
|
+
return undefined
|
76
|
+
}
|
77
|
+
|
78
|
+
get hasRepeater() {
|
79
|
+
return hasRepeater(this._page)
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
/**
|
84
|
+
* @abstract
|
85
|
+
* @implements {PagePreviewPanelMacro}
|
86
|
+
*/
|
87
|
+
export class PreviewPageControllerBase {
|
88
|
+
static PATH = 'preview-controllers/'
|
89
|
+
/**
|
90
|
+
* @type {string}
|
91
|
+
* @protected
|
92
|
+
*/
|
93
|
+
_pageTemplate = PreviewPageControllerBase.PATH + 'page-controller.njk'
|
94
|
+
/**
|
95
|
+
* @protected
|
96
|
+
* @type {Question[]}
|
97
|
+
*/
|
98
|
+
_components = []
|
99
|
+
/**
|
100
|
+
* @type {boolean}
|
101
|
+
* @protected
|
102
|
+
*/
|
103
|
+
_showTitle = true
|
104
|
+
/**
|
105
|
+
* @protected
|
106
|
+
* @type {string}
|
107
|
+
*/
|
108
|
+
_title = ''
|
109
|
+
/**
|
110
|
+
*
|
111
|
+
* @type {PageRenderer}
|
112
|
+
*/
|
113
|
+
#pageRenderer
|
114
|
+
/**
|
115
|
+
* @type { undefined | HighlightClass }
|
116
|
+
* @protected
|
117
|
+
*/
|
118
|
+
_highlighted = undefined
|
119
|
+
/**
|
120
|
+
* @type {string}
|
121
|
+
* @protected
|
122
|
+
*/
|
123
|
+
_guidanceText = ''
|
124
|
+
/**
|
125
|
+
* @type { string }
|
126
|
+
* @protected
|
127
|
+
*/
|
128
|
+
_sectionTitle = ''
|
129
|
+
/**
|
130
|
+
* @type {Markdown}
|
131
|
+
* @protected
|
132
|
+
*/
|
133
|
+
_emptyGuidance = PreviewPageControllerBase.createGuidanceComponent()
|
134
|
+
/**
|
135
|
+
* @type {Markdown}
|
136
|
+
* @protected
|
137
|
+
*/
|
138
|
+
_guidanceComponent = PreviewPageControllerBase.createGuidanceComponent()
|
139
|
+
/**
|
140
|
+
* @protected
|
141
|
+
* @type {boolean}
|
142
|
+
*/
|
143
|
+
_isRepeater = false
|
144
|
+
|
145
|
+
/**
|
146
|
+
* @param {PagePreviewBaseElements} elements
|
147
|
+
* @param {PageRenderer} renderer
|
148
|
+
*/
|
149
|
+
constructor(elements, renderer) {
|
150
|
+
this._guidanceText = elements.guidance
|
151
|
+
this.#pageRenderer = renderer
|
152
|
+
this._title = elements.heading
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* @type {typeof HighlightClass}
|
157
|
+
*/
|
158
|
+
static HighlightClass = HighlightClass
|
159
|
+
|
160
|
+
/**
|
161
|
+
* @returns {Markdown[]}
|
162
|
+
* @protected
|
163
|
+
*/
|
164
|
+
_getGuidanceComponents() {
|
165
|
+
if (this._guidanceText.length) {
|
166
|
+
return [this._guidanceComponent]
|
167
|
+
}
|
168
|
+
if (this._highlighted === 'guidance') {
|
169
|
+
return [this._emptyGuidance]
|
170
|
+
}
|
171
|
+
return []
|
172
|
+
}
|
173
|
+
|
174
|
+
/**
|
175
|
+
* @returns {Markdown[]}
|
176
|
+
* @protected
|
177
|
+
*/
|
178
|
+
get _guidanceComponents() {
|
179
|
+
return this._getGuidanceComponents()
|
180
|
+
}
|
181
|
+
|
182
|
+
/**
|
183
|
+
* @returns {PagePreviewComponent[]}
|
184
|
+
*/
|
185
|
+
get components() {
|
186
|
+
const componentsWithGuidance = /** @type {Question[]} */ ([
|
187
|
+
...this._guidanceComponents,
|
188
|
+
...this._components
|
189
|
+
])
|
190
|
+
|
191
|
+
return componentsWithGuidance.map((component) => {
|
192
|
+
return {
|
193
|
+
model: component.renderInput,
|
194
|
+
questionType: component.componentType
|
195
|
+
}
|
196
|
+
})
|
197
|
+
}
|
198
|
+
|
199
|
+
/**
|
200
|
+
* @returns {string}
|
201
|
+
* @protected
|
202
|
+
*/
|
203
|
+
_getGuidanceText() {
|
204
|
+
return this._guidanceText
|
205
|
+
}
|
206
|
+
|
207
|
+
set guidanceText(text) {
|
208
|
+
this._guidanceText = text
|
209
|
+
this._guidanceComponent.content = text
|
210
|
+
this.render()
|
211
|
+
}
|
212
|
+
|
213
|
+
/**
|
214
|
+
* @returns {string}
|
215
|
+
*/
|
216
|
+
get guidanceText() {
|
217
|
+
return this._getGuidanceText()
|
218
|
+
}
|
219
|
+
|
220
|
+
get guidance() {
|
221
|
+
return {
|
222
|
+
text: this.guidanceText,
|
223
|
+
classes: this._isHighlighted(HighlightClass.GUIDANCE)
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
/**
|
228
|
+
* @param {boolean} showTitle
|
229
|
+
*/
|
230
|
+
set showTitle(showTitle) {
|
231
|
+
this._showTitle = showTitle
|
232
|
+
this.render()
|
233
|
+
}
|
234
|
+
|
235
|
+
get showTitle() {
|
236
|
+
return this._showTitle
|
237
|
+
}
|
238
|
+
|
239
|
+
/**
|
240
|
+
* @returns {{ text: string, classes: string }}
|
241
|
+
*/
|
242
|
+
get pageTitle() {
|
243
|
+
return {
|
244
|
+
text: this.title,
|
245
|
+
classes: this._isHighlighted(HighlightClass.TITLE)
|
246
|
+
}
|
247
|
+
}
|
248
|
+
|
249
|
+
setRepeater() {
|
250
|
+
this._isRepeater = true
|
251
|
+
this.render()
|
252
|
+
}
|
253
|
+
|
254
|
+
unsetRepeater() {
|
255
|
+
this._isRepeater = false
|
256
|
+
this.render()
|
257
|
+
}
|
258
|
+
|
259
|
+
get isRepeater() {
|
260
|
+
return this._isRepeater
|
261
|
+
}
|
262
|
+
|
263
|
+
render() {
|
264
|
+
this.#pageRenderer.render(this._pageTemplate, this)
|
265
|
+
}
|
266
|
+
|
267
|
+
/**
|
268
|
+
* @returns {string}
|
269
|
+
* @protected
|
270
|
+
*/
|
271
|
+
_getTitle() {
|
272
|
+
if (this._title.length) {
|
273
|
+
return this._title
|
274
|
+
}
|
275
|
+
return 'Page heading'
|
276
|
+
}
|
277
|
+
|
278
|
+
/**
|
279
|
+
* @returns {string}
|
280
|
+
*/
|
281
|
+
get title() {
|
282
|
+
return this._getTitle()
|
283
|
+
}
|
284
|
+
|
285
|
+
/**
|
286
|
+
* @param {string} value
|
287
|
+
*/
|
288
|
+
set title(value) {
|
289
|
+
this._title = value
|
290
|
+
this.render()
|
291
|
+
}
|
292
|
+
|
293
|
+
highlightTitle() {
|
294
|
+
this.setHighLighted(HighlightClass.TITLE)
|
295
|
+
}
|
296
|
+
|
297
|
+
/**
|
298
|
+
* @returns {{classes: string, text: string} | undefined}
|
299
|
+
*/
|
300
|
+
get sectionTitle() {
|
301
|
+
if (this.sectionTitleText === undefined) {
|
302
|
+
return undefined
|
303
|
+
}
|
304
|
+
return {
|
305
|
+
classes: this._isHighlighted(HighlightClass.REPEATER),
|
306
|
+
text: this.sectionTitleText
|
307
|
+
}
|
308
|
+
}
|
309
|
+
|
310
|
+
/**
|
311
|
+
* @returns {string|undefined}
|
312
|
+
* @protected
|
313
|
+
*/
|
314
|
+
_getSectionTitleText() {
|
315
|
+
return this._sectionTitle
|
316
|
+
}
|
317
|
+
|
318
|
+
/**
|
319
|
+
* @param {string | undefined} val
|
320
|
+
*/
|
321
|
+
set sectionTitleText(val) {
|
322
|
+
this._sectionTitle = val ?? ''
|
323
|
+
this.render()
|
324
|
+
}
|
325
|
+
|
326
|
+
get sectionTitleText() {
|
327
|
+
return this._getSectionTitleText()
|
328
|
+
}
|
329
|
+
|
330
|
+
/**
|
331
|
+
* Creates a dummy component for when guidance is highlighted
|
332
|
+
* but no guidance text exists
|
333
|
+
* @returns {Markdown}
|
334
|
+
*/
|
335
|
+
static createGuidanceComponent(highlight = true) {
|
336
|
+
const guidanceElement = new ContentElements({
|
337
|
+
type: ComponentType.Markdown,
|
338
|
+
title: 'Guidance component',
|
339
|
+
name: 'guidanceComponent',
|
340
|
+
content: 'Guidance text',
|
341
|
+
options: {}
|
342
|
+
})
|
343
|
+
const guidanceComponent = new Markdown(guidanceElement, questionRenderer)
|
344
|
+
|
345
|
+
if (highlight) {
|
346
|
+
guidanceComponent.highlightContent()
|
347
|
+
}
|
348
|
+
return guidanceComponent
|
349
|
+
}
|
350
|
+
|
351
|
+
highlightGuidance() {
|
352
|
+
this._guidanceComponent.highlightContent()
|
353
|
+
this.setHighLighted(HighlightClass.GUIDANCE)
|
354
|
+
}
|
355
|
+
|
356
|
+
/**
|
357
|
+
* @param {HighlightClass} highlightSection
|
358
|
+
*/
|
359
|
+
setHighLighted(highlightSection) {
|
360
|
+
this._highlighted = highlightSection
|
361
|
+
this.render()
|
362
|
+
}
|
363
|
+
|
364
|
+
clearHighlight() {
|
365
|
+
this._highlighted = undefined
|
366
|
+
|
367
|
+
this._guidanceComponent.unHighlightContent()
|
368
|
+
this.render()
|
369
|
+
}
|
370
|
+
|
371
|
+
/**
|
372
|
+
* @param {string} field
|
373
|
+
* @protected
|
374
|
+
* @returns {string}
|
375
|
+
*/
|
376
|
+
_isHighlighted(field) {
|
377
|
+
return this._highlighted === field ? HIGHLIGHT_CLASS : ''
|
378
|
+
}
|
379
|
+
}
|
380
|
+
|
381
|
+
/**
|
382
|
+
* @import { PageRenderer, PageOverviewElements, PagePreviewBaseElements, QuestionRenderer, QuestionBaseModel } from '~/src/form/form-editor/preview/types.js'
|
383
|
+
* @import { Question } from '~/src/form/form-editor/preview/question.js'
|
384
|
+
* @import { PreviewComponent } from '~/src/form/form-editor/preview/preview.js'
|
385
|
+
* @import { FormDefinition, Page } from '~/src/form/form-definition/types.js'
|
386
|
+
* @import { ComponentDef, MarkdownComponent } from '~/src/components/types.js'
|
387
|
+
* @import { PagePreviewComponent, PagePreviewPanelMacro } from '~/src/form/form-editor/macros/types.js'
|
388
|
+
*/
|