@planning-inspectorate/dynamic-forms 1.12.0 → 1.12.2

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@planning-inspectorate/dynamic-forms",
3
- "version": "1.12.0",
3
+ "version": "1.12.2",
4
4
  "description": "This package is for building GDS forms using a configuration-based approach.",
5
5
  "main": "./src/index.js",
6
6
  "type": "module",
@@ -39,6 +39,7 @@
39
39
  classes: "govuk-radios",
40
40
  idPrefix: question.fieldName,
41
41
  name: question.fieldName,
42
+ hint: { text: question.hint },
42
43
  errorMessage: errors[question.fieldName] and {
43
44
  text: errors[question.fieldName].msg
44
45
  },
@@ -71,6 +72,7 @@
71
72
  classes: "govuk-radios",
72
73
  idPrefix: question.fieldName,
73
74
  name: question.fieldName,
75
+ hint: { text: question.hint },
74
76
  errorMessage: errors[question.fieldName] and {
75
77
  text: errors[question.fieldName].msg
76
78
  },
@@ -100,7 +100,10 @@
100
100
  {{ govukDetails({
101
101
  summaryText: question.summaryText or "Original",
102
102
  html: question.value,
103
- id: question.fieldName + "-unredacted"
103
+ id: question.fieldName + "-unredacted",
104
+ attributes: {
105
+ "data-original": question.valueOriginal
106
+ }
104
107
  }) }}
105
108
 
106
109
  {{ govukTextarea({
@@ -158,7 +161,7 @@
158
161
  * @param {HTMLButtonElement} redactSelectedText
159
162
  * @param {HTMLButtonElement} redactUndo
160
163
  * @param {HTMLButtonElement} redactUndoAll
161
- * @param {HTMLDivElement} unredactedText
164
+ * @param {HTMLDetailsElement} unredactedText
162
165
  * @param {HTMLAnchorElement[]} rejectLinks
163
166
  * @param {import('@azure/ai-text-analytics').PiiEntity[]} suggestions
164
167
  */
@@ -207,7 +210,7 @@
207
210
  }
208
211
  });
209
212
  redactUndoAll.addEventListener('click', () => {
210
- const unredated = unredactedText.textContent?.trim();
213
+ const unredated = unredactedText.dataset.original;
211
214
  if (history.length === 0 && textArea.value === unredated) {
212
215
  showError('No changes to undo');
213
216
  return;
@@ -237,7 +240,7 @@
237
240
  const redactSelectedText = document.querySelector('#redact-selected-text');
238
241
  const redactUndo = document.querySelector('#redact-undo');
239
242
  const redactUndoAll = document.querySelector('#redact-undo-all');
240
- const unredactedText = document.querySelector('#{{ question.fieldName }}-unredacted > div');
243
+ const unredactedText = document.querySelector('#{{ question.fieldName }}-unredacted');
241
244
  const rejectLinks = document.querySelectorAll('[data-redact]');
242
245
  {% if not redactionSuggestions %}
243
246
  {% set redactionSuggestions = [] %}
@@ -256,7 +259,7 @@
256
259
  if (!redactUndoAll || !(redactUndoAll instanceof HTMLButtonElement)) {
257
260
  return;
258
261
  }
259
- if (!unredactedText || !(unredactedText instanceof HTMLDivElement)) {
262
+ if (!unredactedText || !(unredactedText instanceof HTMLDetailsElement)) {
260
263
  return;
261
264
  }
262
265
 
@@ -72,9 +72,11 @@ export default class TextEntryRedactQuestion extends Question {
72
72
  let viewModel = super.prepQuestionForRendering(section, journey, customViewData);
73
73
  viewModel.question.label = this.label;
74
74
  viewModel.question.textEntryCheckbox = this.textEntryCheckbox;
75
- viewModel.question.value = payload ? payload[viewModel.question.fieldName] : viewModel.question.value;
75
+ viewModel.question.value = nl2br(payload ? payload[viewModel.question.fieldName] : viewModel.question.value);
76
76
  viewModel.question.valueRedacted =
77
77
  journey.response.answers[this.fieldName + 'Redacted'] || viewModel.question.value;
78
+ viewModel.question.valueOriginal =
79
+ journey.response.answers[this.fieldName + 'Original'] || viewModel.question.value;
78
80
  viewModel.question.summaryText = this.summaryText;
79
81
  viewModel.showSuggestionsUi = this.showSuggestionsUi;
80
82
  return viewModel;
@@ -139,7 +139,8 @@ describe('./src/dynamic-forms/components/text-entry-redact/question.js', () => {
139
139
  question: 'Redaction Question',
140
140
  fieldName: 'field-name',
141
141
  value: 'value',
142
- valueRedacted: 'value-redacted'
142
+ valueRedacted: 'value-redacted',
143
+ valueOriginal: 'value'
143
144
  },
144
145
  redactionSuggestions: [
145
146
  { category: 'Person', suggestion: 'Test Person' },
@@ -151,6 +152,7 @@ describe('./src/dynamic-forms/components/text-entry-redact/question.js', () => {
151
152
  render: mock.fn((view, data) => nunjucks.render(view + '.njk', data))
152
153
  };
153
154
  const viewModel = question.prepQuestionForRendering(section, journey, customViewData);
155
+ assert.strictEqual(viewModel.question.valueOriginal, 'value');
154
156
  question.renderAction(mockRes, viewModel);
155
157
  assert.strictEqual(mockRes.render.mock.callCount(), 1);
156
158
  const view = mockRes.render.mock.calls[0].result;
@@ -158,6 +160,49 @@ describe('./src/dynamic-forms/components/text-entry-redact/question.js', () => {
158
160
  assert.match(view, /Redaction Question/);
159
161
  assert.match(view, /Redaction suggestions/);
160
162
  assert.match(view, /We have suggested some common redactions/);
163
+ assert.match(view, /data-original="value"/);
164
+ });
165
+ it('should use <br> tags for newlines', () => {
166
+ const question = createQuestion(true);
167
+ const section = {
168
+ name: 'section-name'
169
+ };
170
+ const journey = {
171
+ baseUrl: '',
172
+ taskListUrl: 'task',
173
+ journeyTemplate: 'template',
174
+ journeyTitle: 'title',
175
+ journeyId: 'manage-representations',
176
+ getBackLink: () => {
177
+ return 'back';
178
+ },
179
+ response: {
180
+ answers: {}
181
+ }
182
+ };
183
+ const customViewData = {
184
+ layoutTemplate: 'lib/test-layout.njk',
185
+ question: {
186
+ question: 'Redaction Question',
187
+ fieldName: 'field-name',
188
+ value: 'This is my comment.\nIt has multiple lines.\r\nHere is another line.',
189
+ valueRedacted: 'value-redacted'
190
+ },
191
+ redactionSuggestions: [
192
+ { category: 'Person', suggestion: 'Test Person' },
193
+ { category: 'Address', suggestion: '123 Fake Street' }
194
+ ]
195
+ };
196
+ const nunjucks = configureNunjucks();
197
+ const mockRes = {
198
+ render: mock.fn((view, data) => nunjucks.render(view + '.njk', data))
199
+ };
200
+ const viewModel = question.prepQuestionForRendering(section, journey, customViewData);
201
+ question.renderAction(mockRes, viewModel);
202
+ assert.strictEqual(mockRes.render.mock.callCount(), 1);
203
+ const view = mockRes.render.mock.calls[0].result;
204
+ assert.ok(view);
205
+ assert.match(view, /This is my comment\.<br>It has multiple lines\.<br>Here is another line\./);
161
206
  });
162
207
  it('should format answer for summary', () => {
163
208
  const question = createQuestion();