@planning-inspectorate/dynamic-forms 1.8.0 → 1.9.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/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{% extends layoutTemplate %}
|
|
2
2
|
|
|
3
|
-
{% from "govuk/components/error-summary/macro.njk" import govukErrorSummary %}
|
|
4
|
-
{% from "govuk/components/textarea/macro.njk" import govukTextarea %}
|
|
5
|
-
{% from "govuk/components/label/macro.njk" import govukLabel %}
|
|
6
3
|
{% from "govuk/components/button/macro.njk" import govukButton %}
|
|
7
4
|
{% from "govuk/components/checkboxes/macro.njk" import govukCheckboxes %}
|
|
8
|
-
{% from "govuk/components/
|
|
5
|
+
{% from "govuk/components/details/macro.njk" import govukDetails %}
|
|
6
|
+
{% from "govuk/components/error-summary/macro.njk" import govukErrorSummary %}
|
|
7
|
+
{% from "govuk/components/label/macro.njk" import govukLabel %}
|
|
9
8
|
{% from "govuk/components/table/macro.njk" import govukTable %}
|
|
9
|
+
{% from "govuk/components/textarea/macro.njk" import govukTextarea %}
|
|
10
10
|
|
|
11
11
|
{% block before_content %}
|
|
12
12
|
<div class="govuk-grid-row">
|
|
@@ -24,14 +24,9 @@
|
|
|
24
24
|
{{ super() }}
|
|
25
25
|
{% endblock before_content %}
|
|
26
26
|
|
|
27
|
-
{% set columnWidth = 'govuk-grid-column-two-thirds' %}
|
|
28
|
-
{% if showSuggestionsUi %}
|
|
29
|
-
{% set columnWidth = 'govuk-grid-column-one-half' %}
|
|
30
|
-
{% endif %}
|
|
31
|
-
|
|
32
27
|
{% block content %}
|
|
33
28
|
<div class="govuk-grid-row">
|
|
34
|
-
<div class="
|
|
29
|
+
<div class="govuk-grid-column-two-thirds">
|
|
35
30
|
<form action="" method="post" novalidate>
|
|
36
31
|
<input type="hidden" name="_csrf" value="{{ _csrf }}">
|
|
37
32
|
|
|
@@ -53,15 +48,59 @@
|
|
|
53
48
|
{% include question.html ignore missing %}
|
|
54
49
|
{% endif %}
|
|
55
50
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
{% if showSuggestionsUi %}
|
|
52
|
+
<h2 class="govuk-heading-m">Redaction suggestions</h2>
|
|
53
|
+
{% set hasSuggestions = redactionSuggestions.length > 0 %}
|
|
54
|
+
{% if hasSuggestions %}
|
|
55
|
+
<p class="govuk-body">
|
|
56
|
+
We have suggested some common redactions and hidden these for you.
|
|
57
|
+
To make these visible again, 'Reject' each suggestion.
|
|
58
|
+
</p>
|
|
59
|
+
{% set suggestionTableRows = [] %}
|
|
60
|
+
{% for s in redactionSuggestions %}
|
|
61
|
+
{% set category = s.category %}
|
|
62
|
+
{% if s.subCategory %}
|
|
63
|
+
{% set category = category + " (" + s.subCategory + ")" %}
|
|
64
|
+
{% endif %}
|
|
65
|
+
{% set action = 'Accept' %}
|
|
66
|
+
{% if s.accepted %}
|
|
67
|
+
{% set action = 'Reject' %}
|
|
68
|
+
{% endif %}
|
|
69
|
+
{% set suggestionTableRows = (suggestionTableRows.push([
|
|
70
|
+
{text: s.text},
|
|
71
|
+
{text: category },
|
|
72
|
+
{
|
|
73
|
+
html: '<a href="#" class="govuk-link" data-redact="suggestion-reject-' + loop.index0 + '">' + action + '</a>'
|
|
74
|
+
}
|
|
75
|
+
]), suggestionTableRows) %}
|
|
76
|
+
{% endfor %}
|
|
77
|
+
{{ govukTable({
|
|
78
|
+
head: [
|
|
79
|
+
{
|
|
80
|
+
text: "Redaction suggestion"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
text: "Type of information"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
text: "Action"
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
rows: suggestionTableRows
|
|
90
|
+
}) }}
|
|
91
|
+
{% else %}
|
|
92
|
+
<p class="govuk-body">
|
|
93
|
+
No redaction suggestions found.
|
|
94
|
+
</p>
|
|
95
|
+
{% endif %}
|
|
96
|
+
{% endif %}
|
|
60
97
|
|
|
61
|
-
|
|
98
|
+
<h2 class="govuk-heading-m">Redaction preview</h2>
|
|
99
|
+
|
|
100
|
+
{{ govukDetails({
|
|
101
|
+
summaryText: question.summaryText or "Original",
|
|
62
102
|
html: question.value,
|
|
63
|
-
id: question.fieldName + "-unredacted"
|
|
64
|
-
classes: "govuk-!-margin-top-0"
|
|
103
|
+
id: question.fieldName + "-unredacted"
|
|
65
104
|
}) }}
|
|
66
105
|
|
|
67
106
|
{{ govukTextarea({
|
|
@@ -75,7 +114,11 @@
|
|
|
75
114
|
errorMessage: errors[question.fieldName] and {
|
|
76
115
|
text: errors[question.fieldName].msg
|
|
77
116
|
},
|
|
78
|
-
classes: question.inputClasses
|
|
117
|
+
classes: question.inputClasses,
|
|
118
|
+
attributes: {
|
|
119
|
+
readonly: true
|
|
120
|
+
},
|
|
121
|
+
rows: textAreaRows or 8
|
|
79
122
|
}) }}
|
|
80
123
|
|
|
81
124
|
<div class="govuk-button-group">
|
|
@@ -108,48 +151,6 @@
|
|
|
108
151
|
}) }}
|
|
109
152
|
</form>
|
|
110
153
|
</div>
|
|
111
|
-
{% if showSuggestionsUi %}
|
|
112
|
-
<div class="govuk-grid-column-one-half">
|
|
113
|
-
<h2 class="govuk-heading-m">Redaction suggestions</h2>
|
|
114
|
-
<p class="govuk-body">
|
|
115
|
-
This section includes system suggestions for redactions.
|
|
116
|
-
Each row shows the text that is suggested for redaction and the category detected.
|
|
117
|
-
They are all redacted by default, you can reject any that should not be redacted by clicking the "Reject" link next to each suggestion.
|
|
118
|
-
</p>
|
|
119
|
-
{% set suggestionTableRows = [] %}
|
|
120
|
-
{% for s in redactionSuggestions %}
|
|
121
|
-
{% set category = s.category %}
|
|
122
|
-
{% if s.subCategory %}
|
|
123
|
-
{% set category = category + " (" + s.subCategory + ")" %}
|
|
124
|
-
{% endif %}
|
|
125
|
-
{% set action = 'Accept' %}
|
|
126
|
-
{% if s.accepted %}
|
|
127
|
-
{% set action = 'Reject' %}
|
|
128
|
-
{% endif %}
|
|
129
|
-
{% set suggestionTableRows = (suggestionTableRows.push([
|
|
130
|
-
{text: s.text},
|
|
131
|
-
{text: category },
|
|
132
|
-
{
|
|
133
|
-
html: '<a href="#" class="govuk-link" data-redact="suggestion-reject-' + loop.index0 + '">' + action + '</a>'
|
|
134
|
-
}
|
|
135
|
-
]), suggestionTableRows) %}
|
|
136
|
-
{% endfor %}
|
|
137
|
-
{{ govukTable({
|
|
138
|
-
head: [
|
|
139
|
-
{
|
|
140
|
-
text: "Text"
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
text: "Category"
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
text: "Action"
|
|
147
|
-
}
|
|
148
|
-
],
|
|
149
|
-
rows: suggestionTableRows
|
|
150
|
-
}) }}
|
|
151
|
-
</div>
|
|
152
|
-
{% endif %}
|
|
153
154
|
|
|
154
155
|
<script {% if cspNonce %}nonce={{ cspNonce }}{% endif %}>
|
|
155
156
|
/**
|
|
@@ -27,8 +27,18 @@ export default class TextEntryRedactQuestion extends Question {
|
|
|
27
27
|
* @param {string|undefined} [params.label] if defined this show as a label for the input and the question will just be a standard h1
|
|
28
28
|
* @param {boolean} [params.onlyShowRedactedValueForSummary] whether to only show redacted value for summary
|
|
29
29
|
* @param {boolean} [params.useRedactedFieldNameForSave] whether to use the redacted field name when saving answers
|
|
30
|
+
* @param {boolean} [params.showSuggestionsUi] use the suggestions UI for this question
|
|
31
|
+
* @param {string} [params.summaryText] summaryText to use with the details component
|
|
30
32
|
*/
|
|
31
|
-
constructor({
|
|
33
|
+
constructor({
|
|
34
|
+
textEntryCheckbox,
|
|
35
|
+
label,
|
|
36
|
+
onlyShowRedactedValueForSummary,
|
|
37
|
+
useRedactedFieldNameForSave,
|
|
38
|
+
showSuggestionsUi,
|
|
39
|
+
summaryText,
|
|
40
|
+
...params
|
|
41
|
+
}) {
|
|
32
42
|
super({
|
|
33
43
|
...params,
|
|
34
44
|
viewFolder: 'text-entry-redact'
|
|
@@ -38,6 +48,8 @@ export default class TextEntryRedactQuestion extends Question {
|
|
|
38
48
|
this.label = label;
|
|
39
49
|
this.onlyShowRedactedValueForSummary = onlyShowRedactedValueForSummary;
|
|
40
50
|
this.useRedactedFieldNameForSave = useRedactedFieldNameForSave;
|
|
51
|
+
this.showSuggestionsUi = showSuggestionsUi;
|
|
52
|
+
this.summaryText = summaryText;
|
|
41
53
|
}
|
|
42
54
|
|
|
43
55
|
async getDataToSave(req, journeyResponse) {
|
|
@@ -58,6 +70,8 @@ export default class TextEntryRedactQuestion extends Question {
|
|
|
58
70
|
viewModel.question.value = payload ? payload[viewModel.question.fieldName] : viewModel.question.value;
|
|
59
71
|
viewModel.question.valueRedacted =
|
|
60
72
|
journey.response.answers[this.fieldName + 'Redacted'] || viewModel.question.value;
|
|
73
|
+
viewModel.question.summaryText = this.summaryText;
|
|
74
|
+
viewModel.showSuggestionsUi = this.showSuggestionsUi;
|
|
61
75
|
return viewModel;
|
|
62
76
|
}
|
|
63
77
|
|
|
@@ -12,7 +12,7 @@ describe('./src/dynamic-forms/components/text-entry-redact/question.js', () => {
|
|
|
12
12
|
const HINT = 'hint';
|
|
13
13
|
const LABEL = 'A label';
|
|
14
14
|
|
|
15
|
-
function createQuestion() {
|
|
15
|
+
function createQuestion(showSuggestionsUi = false) {
|
|
16
16
|
return new TextEntryRedactQuestion({
|
|
17
17
|
title: TITLE,
|
|
18
18
|
question: QUESTION,
|
|
@@ -20,7 +20,8 @@ describe('./src/dynamic-forms/components/text-entry-redact/question.js', () => {
|
|
|
20
20
|
validators: VALIDATORS,
|
|
21
21
|
html: HTML,
|
|
22
22
|
hint: HINT,
|
|
23
|
-
label: LABEL
|
|
23
|
+
label: LABEL,
|
|
24
|
+
showSuggestionsUi
|
|
24
25
|
});
|
|
25
26
|
}
|
|
26
27
|
it('should create', () => {
|
|
@@ -72,11 +73,10 @@ describe('./src/dynamic-forms/components/text-entry-redact/question.js', () => {
|
|
|
72
73
|
const view = mockRes.render.mock.calls[0].result;
|
|
73
74
|
assert.ok(view);
|
|
74
75
|
assert.match(view, /Redaction Question/);
|
|
75
|
-
assert.match(view, /govuk-grid-column-two-thirds">\s+<form/);
|
|
76
76
|
assert.doesNotMatch(view, /Redaction suggestions/);
|
|
77
77
|
});
|
|
78
78
|
it('should render suggestions view', () => {
|
|
79
|
-
const question = createQuestion();
|
|
79
|
+
const question = createQuestion(true);
|
|
80
80
|
const section = {
|
|
81
81
|
name: 'section-name'
|
|
82
82
|
};
|
|
@@ -94,7 +94,6 @@ describe('./src/dynamic-forms/components/text-entry-redact/question.js', () => {
|
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
96
|
const customViewData = {
|
|
97
|
-
showSuggestionsUi: true,
|
|
98
97
|
layoutTemplate: 'lib/test-layout.njk',
|
|
99
98
|
question: {
|
|
100
99
|
question: 'Redaction Question',
|
|
@@ -113,8 +112,51 @@ describe('./src/dynamic-forms/components/text-entry-redact/question.js', () => {
|
|
|
113
112
|
const view = mockRes.render.mock.calls[0].result;
|
|
114
113
|
assert.ok(view);
|
|
115
114
|
assert.match(view, /Redaction Question/);
|
|
116
|
-
assert.match(view, /govuk-grid-column-one-half">\s+<form/);
|
|
117
|
-
assert.doesNotMatch(view, /govuk-grid-column-two-thirds">\s+<form/);
|
|
118
115
|
assert.match(view, /Redaction suggestions/);
|
|
116
|
+
assert.match(view, /No redaction suggestions found\./);
|
|
117
|
+
});
|
|
118
|
+
it('should render suggestions view with data', () => {
|
|
119
|
+
const question = createQuestion(true);
|
|
120
|
+
const section = {
|
|
121
|
+
name: 'section-name'
|
|
122
|
+
};
|
|
123
|
+
const journey = {
|
|
124
|
+
baseUrl: '',
|
|
125
|
+
taskListUrl: 'task',
|
|
126
|
+
journeyTemplate: 'template',
|
|
127
|
+
journeyTitle: 'title',
|
|
128
|
+
journeyId: 'manage-representations',
|
|
129
|
+
getBackLink: () => {
|
|
130
|
+
return 'back';
|
|
131
|
+
},
|
|
132
|
+
response: {
|
|
133
|
+
answers: {}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const customViewData = {
|
|
137
|
+
layoutTemplate: 'lib/test-layout.njk',
|
|
138
|
+
question: {
|
|
139
|
+
question: 'Redaction Question',
|
|
140
|
+
fieldName: 'field-name',
|
|
141
|
+
value: 'value',
|
|
142
|
+
valueRedacted: 'value-redacted'
|
|
143
|
+
},
|
|
144
|
+
redactionSuggestions: [
|
|
145
|
+
{ category: 'Person', suggestion: 'Test Person' },
|
|
146
|
+
{ category: 'Address', suggestion: '123 Fake Street' }
|
|
147
|
+
]
|
|
148
|
+
};
|
|
149
|
+
const nunjucks = configureNunjucks();
|
|
150
|
+
const mockRes = {
|
|
151
|
+
render: mock.fn((view, data) => nunjucks.render(view + '.njk', data))
|
|
152
|
+
};
|
|
153
|
+
const viewModel = question.prepQuestionForRendering(section, journey, customViewData);
|
|
154
|
+
question.renderAction(mockRes, viewModel);
|
|
155
|
+
assert.strictEqual(mockRes.render.mock.callCount(), 1);
|
|
156
|
+
const view = mockRes.render.mock.calls[0].result;
|
|
157
|
+
assert.ok(view);
|
|
158
|
+
assert.match(view, /Redaction Question/);
|
|
159
|
+
assert.match(view, /Redaction suggestions/);
|
|
160
|
+
assert.match(view, /We have suggested some common redactions/);
|
|
119
161
|
});
|
|
120
162
|
});
|