From 02514df9fadcddab6305a58de48e3a01d60731c4 Mon Sep 17 00:00:00 2001 From: Tom Byers Date: Tue, 14 Jul 2020 16:45:35 +0100 Subject: [PATCH 01/37] Bring in Jinja and Sass for text-input component --- app/assets/stylesheets/govuk-frontend/_all.scss | 1 + gulpfile.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/govuk-frontend/_all.scss b/app/assets/stylesheets/govuk-frontend/_all.scss index 6776fb95a..2a49596b4 100644 --- a/app/assets/stylesheets/govuk-frontend/_all.scss +++ b/app/assets/stylesheets/govuk-frontend/_all.scss @@ -27,6 +27,7 @@ $govuk-assets-path: "/static/"; @import 'components/details/_details'; @import 'components/radios/_radios'; @import 'components/checkboxes/_checkboxes'; +@import 'components/input/_input'; @import "utilities/all"; @import "overrides/all"; diff --git a/gulpfile.js b/gulpfile.js index d8e098977..d8e8686d9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -70,7 +70,8 @@ const copy = { 'fieldset', 'hint', 'label', - 'checkboxes' + 'checkboxes', + 'input' ]; let done = 0; From 57d5f31be47f31391622707d0bfdaeecd8a989c4 Mon Sep 17 00:00:00 2001 From: Tom Byers Date: Tue, 14 Jul 2020 16:24:40 +0100 Subject: [PATCH 02/37] Add GovukTextInputField - extends StringField --- app/main/forms.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/app/main/forms.py b/app/main/forms.py index 77c6d7cfd..323605481 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -186,6 +186,39 @@ def password(label='Password'): CommonlyUsedPassword(message='Choose a password that’s harder to guess')]) +class GovukTextInputField(StringField): + def __init__(self, label='', validators=None, param_extensions=None, **kwargs): + super(GovukTextInputField, self).__init__(label, validators, **kwargs) + self.param_extensions = param_extensions + + # self.__call__ renders the HTML for the field by: + # 1. delegating to self.meta.render_field which + # 2. calls field.widget + # this bypasses that by making self.widget a method with the same interface as widget.__call__ + def widget(self, field, **kwargs): + # error messages + error_message = None + if field.errors: + error_message = {"text": " ".join(field.errors).strip()} + + # convert to parameters that govuk understands + params = { + "name": field.name, + "id": field.id, + "label": {"text": field.label.text}, + "value": field.data, + "classes": "govuk-!-width-two-thirds", + "errorMessage": error_message, + } + + # extend default params with any sent in + if self.param_extensions: + params.update(self.param_extensions) + + return Markup( + render_template('vendor/govuk-frontend/components/input/template.njk', params=params)) + + class SMSCode(StringField): validators = [ DataRequired(message='Cannot be empty'), From 87beaf49ae285b91fb2f0e644e8e65ec416a5681 Mon Sep 17 00:00:00 2001 From: Tom Byers Date: Tue, 14 Jul 2020 16:51:11 +0100 Subject: [PATCH 03/37] Use GovukTextInputField in RenameServiceForm Includes changes to templates that use this form and associated tests. --- app/main/forms.py | 2 +- app/templates/views/service-settings/name-local.html | 3 +-- app/templates/views/service-settings/name.html | 3 +-- tests/app/main/views/test_service_settings.py | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index 323605481..c3d72b74d 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -923,7 +923,7 @@ class TextNotReceivedForm(StripWhitespaceForm): class RenameServiceForm(StripWhitespaceForm): - name = StringField( + name = GovukTextInputField( u'Service name', validators=[ DataRequired(message='Cannot be empty'), diff --git a/app/templates/views/service-settings/name-local.html b/app/templates/views/service-settings/name-local.html index 30eb83640..fa48fbeac 100644 --- a/app/templates/views/service-settings/name-local.html +++ b/app/templates/views/service-settings/name-local.html @@ -1,6 +1,5 @@ {% extends "withnav_template.html" %} -{% from "components/textbox.html" import textbox %} {% from "components/page-header.html" import page_header %} {% from "components/page-footer.html" import page_footer %} {% from "components/form.html" import form_wrapper %} @@ -38,7 +37,7 @@ {% call form_wrapper() %} - {{ textbox(form.name) }} + {{ form.name }} {{ page_footer('Save') }} {% endcall %} diff --git a/app/templates/views/service-settings/name.html b/app/templates/views/service-settings/name.html index bec0c936a..921b2a5d4 100644 --- a/app/templates/views/service-settings/name.html +++ b/app/templates/views/service-settings/name.html @@ -1,6 +1,5 @@ {% extends "withnav_template.html" %} -{% from "components/textbox.html" import textbox %} {% from "components/page-header.html" import page_header %} {% from "components/page-footer.html" import page_footer %} {% from "components/form.html" import form_wrapper %} @@ -29,7 +28,7 @@ {% call form_wrapper() %} - {{ textbox(form.name) }} + {{ form.name }} {{ page_footer('Save') }} {% endcall %} diff --git a/tests/app/main/views/test_service_settings.py b/tests/app/main/views/test_service_settings.py index d7a1b3da3..2cdbb6505 100644 --- a/tests/app/main/views/test_service_settings.py +++ b/tests/app/main/views/test_service_settings.py @@ -493,7 +493,7 @@ def test_service_name_change_fails_if_new_name_has_less_than_2_alphanumeric_char ) assert not mock_service_name_is_unique.called assert not mock_update_service.called - assert page.find("span", {"class": "error-message"}) + assert page.find("span", {"class": "govuk-error-message"}) @pytest.mark.parametrize('user, expected_text, expected_link', [ From a3e661830d06a174aa51c9eed9f55f9d1b88d6f2 Mon Sep 17 00:00:00 2001 From: Tom Byers Date: Thu, 6 Aug 2020 15:36:34 +0100 Subject: [PATCH 04/37] Convert text inputs on ServiceUpdateEmailBranding Includes changes to templates that use this form and associated tests. --- app/assets/javascripts/colourPreview.js | 4 ++-- .../stylesheets/govuk-frontend/extensions.scss | 4 ++++ app/main/forms.py | 12 ++++++++---- .../views/email-branding/manage-branding.html | 8 ++++---- tests/app/main/views/test_email_branding.py | 8 ++++---- tests/javascripts/colourPreview.test.js | 8 ++++---- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/colourPreview.js b/app/assets/javascripts/colourPreview.js index 52e2d4f4d..20b5e0498 100644 --- a/app/assets/javascripts/colourPreview.js +++ b/app/assets/javascripts/colourPreview.js @@ -8,9 +8,9 @@ this.start = component => { - this.$input = $('input', component); + this.$input = $(component); - $(component).append( + this.$input.closest('.govuk-form-group').append( this.$preview = $('') ); diff --git a/app/assets/stylesheets/govuk-frontend/extensions.scss b/app/assets/stylesheets/govuk-frontend/extensions.scss index 80cce8a3b..8197b34ad 100644 --- a/app/assets/stylesheets/govuk-frontend/extensions.scss +++ b/app/assets/stylesheets/govuk-frontend/extensions.scss @@ -48,3 +48,7 @@ $govuk-grid-widths: ( seven-eighths: 87.5%, full: 100% ); + +.govuk-input--width-6 { + max-width: 14ex; +} diff --git a/app/main/forms.py b/app/main/forms.py index c3d72b74d..ca30ae3d3 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1554,13 +1554,17 @@ class PreviewBranding(StripWhitespaceForm): class ServiceUpdateEmailBranding(StripWhitespaceForm): - name = StringField('Name of brand') - text = StringField('Text') - colour = StringField( + name = GovukTextInputField('Name of brand') + text = GovukTextInputField('Text') + colour = GovukTextInputField( 'Colour', validators=[ Regexp(regex="^$|^#(?:[0-9a-fA-F]{3}){1,2}$", message='Must be a valid color hex code (starting with #)') - ] + ], + param_extensions={ + "classes": "govuk-input--width-6", + "attributes": {"data-module": "colour-preview"} + } ) file = FileField_wtf('Upload a PNG logo', validators=[FileAllowed(['png'], 'PNG Images only!')]) brand_type = RadioField( diff --git a/app/templates/views/email-branding/manage-branding.html b/app/templates/views/email-branding/manage-branding.html index 7d757aec3..440e5d204 100644 --- a/app/templates/views/email-branding/manage-branding.html +++ b/app/templates/views/email-branding/manage-branding.html @@ -29,10 +29,10 @@ {{ file_upload(form.file, button_text='{} logo'.format('Update' if email_branding else 'Upload')) }} {% call form_wrapper() %}
-
{{textbox(form.name)}}
-
{{textbox(form.text)}}
- {{ textbox(form.colour, width='1-4', colour_preview=True) }} - {{ radios(form.brand_type) }} +
{{form.name}}
+
{{form.text}}
+ {{ form.colour }} + {{ radios(form.brand_type) }} {{ page_footer( 'Save', button_name='operation', diff --git a/tests/app/main/views/test_email_branding.py b/tests/app/main/views/test_email_branding.py index adfc89f87..787e108c2 100644 --- a/tests/app/main/views/test_email_branding.py +++ b/tests/app/main/views/test_email_branding.py @@ -78,9 +78,9 @@ def test_create_email_branding_does_not_show_any_branding_info( page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert page.select_one('#logo-img > img') is None - assert page.select_one('#name').attrs.get('value') == '' - assert page.select_one('#text').attrs.get('value') == '' - assert page.select_one('#colour').attrs.get('value') == '' + assert page.select_one('#name').attrs.get('value') is None + assert page.select_one('#text').attrs.get('value') is None + assert page.select_one('#colour').attrs.get('value') is None def test_create_new_email_branding_without_logo( @@ -141,7 +141,7 @@ def test_create_email_branding_requires_a_name_when_submitting_logo_details( _expected_status=200, ) - assert page.select_one('.error-message').text.strip() == 'This field is required' + assert page.select_one('.govuk-error-message').text.strip() == 'Error: This field is required' assert mock_create_email_branding.called is False diff --git a/tests/javascripts/colourPreview.test.js b/tests/javascripts/colourPreview.test.js index 92a511781..ab37f8e7e 100644 --- a/tests/javascripts/colourPreview.test.js +++ b/tests/javascripts/colourPreview.test.js @@ -18,14 +18,14 @@ describe('Colour preview', () => { // set up DOM document.body.innerHTML = ` -
-