mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-11 17:38:50 -04:00
Merge pull request #2743 from GSA/cleanup/govuk-uswds-checkbox
Cleanup/govuk uswds checkbox
This commit is contained in:
@@ -655,7 +655,7 @@ class RegisterUserFromOrgInviteForm(StripWhitespaceForm):
|
||||
auth_type = HiddenField("auth_type", validators=[DataRequired()])
|
||||
|
||||
|
||||
def govuk_checkbox_field_widget(self, field, param_extensions=None, **kwargs):
|
||||
def uswds_checkbox_field_widget(self, field, param_extensions=None, **kwargs):
|
||||
# error messages
|
||||
error_message = None
|
||||
if field.errors:
|
||||
@@ -695,7 +695,7 @@ def govuk_checkbox_field_widget(self, field, param_extensions=None, **kwargs):
|
||||
) # nosec
|
||||
|
||||
|
||||
def govuk_checkboxes_field_widget(
|
||||
def uswds_checkboxes_field_widget(
|
||||
self, field, wrap_in_collapsible=False, param_extensions=None, **kwargs
|
||||
):
|
||||
def _wrap_in_collapsible(field_label, checkboxes_string):
|
||||
@@ -812,9 +812,9 @@ def govuk_radios_field_widget(self, field, param_extensions=None, **kwargs):
|
||||
) # nosec
|
||||
|
||||
|
||||
class GovukCheckboxField(BooleanField):
|
||||
class USWDSCheckboxField(BooleanField):
|
||||
def __init__(self, label="", validators=None, param_extensions=None, **kwargs):
|
||||
super(GovukCheckboxField, self).__init__(
|
||||
super(USWDSCheckboxField, self).__init__(
|
||||
label, validators, false_values=None, **kwargs
|
||||
)
|
||||
self.param_extensions = param_extensions
|
||||
@@ -824,17 +824,17 @@ class GovukCheckboxField(BooleanField):
|
||||
# 2. calls field.widget
|
||||
# this bypasses that by making self.widget a method with the same interface as widget.__call__
|
||||
def widget(self, field, param_extensions=None, **kwargs):
|
||||
return govuk_checkbox_field_widget(
|
||||
return uswds_checkbox_field_widget(
|
||||
self, field, param_extensions=param_extensions, **kwargs
|
||||
)
|
||||
|
||||
|
||||
# based on work done by @richardjpope: https://github.com/richardjpope/recourse/blob/master/recourse/forms.py#L6
|
||||
class GovukCheckboxesField(SelectMultipleField):
|
||||
class USWDSCheckboxesField(SelectMultipleField):
|
||||
render_as_list = False
|
||||
|
||||
def __init__(self, label="", validators=None, param_extensions=None, **kwargs):
|
||||
super(GovukCheckboxesField, self).__init__(label, validators, **kwargs)
|
||||
super(USWDSCheckboxesField, self).__init__(label, validators, **kwargs)
|
||||
self.param_extensions = param_extensions
|
||||
|
||||
def get_item_from_option(self, option):
|
||||
@@ -854,32 +854,32 @@ class GovukCheckboxesField(SelectMultipleField):
|
||||
# 2. calls field.widget
|
||||
# this bypasses that by making self.widget a method with the same interface as widget.__call__
|
||||
def widget(self, field, param_extensions=None, **kwargs):
|
||||
return govuk_checkboxes_field_widget(
|
||||
return uswds_checkboxes_field_widget(
|
||||
self, field, param_extensions=param_extensions, **kwargs
|
||||
)
|
||||
|
||||
|
||||
# Wraps checkboxes rendering in HTML needed by the collapsible JS
|
||||
class GovukCollapsibleCheckboxesField(GovukCheckboxesField):
|
||||
class USWDSCollapsibleCheckboxesField(USWDSCheckboxesField):
|
||||
def __init__(
|
||||
self, label="", validators=None, field_label="", param_extensions=None, **kwargs
|
||||
):
|
||||
super(GovukCollapsibleCheckboxesField, self).__init__(
|
||||
super(USWDSCollapsibleCheckboxesField, self).__init__(
|
||||
label, validators, param_extensions, **kwargs
|
||||
)
|
||||
self.field_label = field_label
|
||||
|
||||
def widget(self, field, **kwargs):
|
||||
return govuk_checkboxes_field_widget(
|
||||
return uswds_checkboxes_field_widget(
|
||||
self, field, wrap_in_collapsible=True, param_extensions=None, **kwargs
|
||||
)
|
||||
|
||||
|
||||
# GovukCollapsibleCheckboxesField adds an ARIA live-region to the hint and wraps the render in HTML needed by the
|
||||
# USWDSCollapsibleCheckboxesField adds an ARIA live-region to the hint and wraps the render in HTML needed by the
|
||||
# collapsible JS
|
||||
# NestedFieldMixin puts the items into a tree hierarchy, pre-rendering the sub-trees of the top-level items
|
||||
class GovukCollapsibleNestedCheckboxesField(
|
||||
NestedFieldMixin, GovukCollapsibleCheckboxesField
|
||||
class USWDSCollapsibleNestedCheckboxesField(
|
||||
NestedFieldMixin, USWDSCollapsibleCheckboxesField
|
||||
):
|
||||
NONE_OPTION_VALUE = None
|
||||
render_as_list = True
|
||||
@@ -998,7 +998,7 @@ class BasePermissionsForm(StripWhitespaceForm):
|
||||
for item in ([{"name": "Templates", "id": None}] + all_template_folders)
|
||||
]
|
||||
|
||||
folder_permissions = GovukCollapsibleNestedCheckboxesField(
|
||||
folder_permissions = USWDSCollapsibleNestedCheckboxesField(
|
||||
"Folders this team member can see", field_label="folder"
|
||||
)
|
||||
|
||||
@@ -1012,7 +1012,7 @@ class BasePermissionsForm(StripWhitespaceForm):
|
||||
validators=[DataRequired()],
|
||||
)
|
||||
|
||||
permissions_field = GovukCheckboxesField(
|
||||
permissions_field = USWDSCheckboxesField(
|
||||
"Permissions",
|
||||
filters=[filter_by_permissions],
|
||||
choices=[(value, label) for value, label in permission_options],
|
||||
@@ -1422,7 +1422,7 @@ class ServiceContactDetailsForm(StripWhitespaceForm):
|
||||
|
||||
class ServiceReplyToEmailForm(StripWhitespaceForm):
|
||||
email_address = email_address(label="Reply-to email address", gov_user=False)
|
||||
is_default = GovukCheckboxField("Make this email address the default")
|
||||
is_default = USWDSCheckboxField("Make this email address the default")
|
||||
|
||||
|
||||
class ServiceSmsSenderForm(StripWhitespaceForm):
|
||||
@@ -1436,11 +1436,11 @@ class ServiceSmsSenderForm(StripWhitespaceForm):
|
||||
DoesNotStartWithDoubleZero(),
|
||||
],
|
||||
)
|
||||
is_default = GovukCheckboxField("Make this text message sender the default")
|
||||
is_default = USWDSCheckboxField("Make this text message sender the default")
|
||||
|
||||
|
||||
class ServiceEditInboundNumberForm(StripWhitespaceForm):
|
||||
is_default = GovukCheckboxField("Make this text message sender the default")
|
||||
is_default = USWDSCheckboxField("Make this text message sender the default")
|
||||
|
||||
|
||||
class AdminNotesForm(StripWhitespaceForm):
|
||||
@@ -1528,7 +1528,7 @@ class GuestList(StripWhitespaceForm):
|
||||
class DateFilterForm(StripWhitespaceForm):
|
||||
start_date = GovukDateField("Start Date", [validators.optional()])
|
||||
end_date = GovukDateField("End Date", [validators.optional()])
|
||||
include_from_test_key = GovukCheckboxField("Include test keys")
|
||||
include_from_test_key = USWDSCheckboxField("Include test keys")
|
||||
|
||||
|
||||
class RequiredDateFilterForm(StripWhitespaceForm):
|
||||
@@ -1732,7 +1732,7 @@ class TemplateFolderForm(StripWhitespaceForm):
|
||||
(item.id, item.name) for item in all_service_users
|
||||
]
|
||||
|
||||
users_with_permission = GovukCollapsibleCheckboxesField(
|
||||
users_with_permission = USWDSCollapsibleCheckboxesField(
|
||||
"Team members who can see this folder", field_label="team member"
|
||||
)
|
||||
name = GovukTextInputField(
|
||||
@@ -1851,7 +1851,7 @@ class TemplateAndFoldersSelectionForm(Form):
|
||||
return self.move_to_new_folder_name.data
|
||||
return None
|
||||
|
||||
templates_and_folders = GovukCheckboxesField(
|
||||
templates_and_folders = USWDSCheckboxesField(
|
||||
"Choose templates or folders",
|
||||
validators=[required_for_ops("move-to-new-folder", "move-to-existing-folder")],
|
||||
choices=[], # added to keep order of arguments, added properly in __init__
|
||||
@@ -1883,7 +1883,7 @@ class TemplateAndFoldersSelectionForm(Form):
|
||||
|
||||
|
||||
class AdminClearCacheForm(StripWhitespaceForm):
|
||||
model_type = GovukCheckboxesField(
|
||||
model_type = USWDSCheckboxesField(
|
||||
"What do you want to clear today",
|
||||
)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
visuallyHiddenText: params.errorMessage.visuallyHiddenText
|
||||
}) | indent(2) | trim }}
|
||||
{% endif %}
|
||||
<div class="govuk-checkboxes {%- if params.classes %} {{ params.classes }}{% endif %}"
|
||||
<div class="usa-checkbox-group {%- if params.classes %} {{ params.classes }}{% endif %}"
|
||||
{%- for attribute, value in params.attributes %} {{ attribute }}="{{ value }}"{% endfor %}
|
||||
{%- if isConditional %} data-module="checkboxes"{% endif -%}>
|
||||
{% for item in params.items %}
|
||||
@@ -60,8 +60,8 @@
|
||||
{% set itemHintId = id + "-item-hint" if hasHint else "" %}
|
||||
{% set itemDescribedBy = describedBy if not hasFieldset else "" %}
|
||||
{% set itemDescribedBy = (itemDescribedBy + " " + itemHintId) | trim %}
|
||||
<div class="govuk-checkboxes__item">
|
||||
<input class="govuk-checkboxes__input" id="{{ id }}" name="{{ name }}" type="checkbox" value="{{ item.value }}"
|
||||
<div class="usa-checkbox">
|
||||
<input class="usa-checkbox__input" id="{{ id }}" name="{{ name }}" type="checkbox" value="{{ item.value }}"
|
||||
{{-" checked" if item.checked }}
|
||||
{{-" disabled" if item.disabled }}
|
||||
{%- if item.conditional %} data-aria-controls="{{ conditionalId }}"{% endif -%}
|
||||
@@ -70,14 +70,14 @@
|
||||
{{ usaLabel({
|
||||
html: item.html,
|
||||
text: item.text,
|
||||
classes: 'govuk-checkboxes__label' + (' ' + item.label.classes if item.label.classes),
|
||||
classes: 'usa-checkbox__label' + (' ' + item.label.classes if item.label.classes),
|
||||
attributes: item.label.attributes,
|
||||
for: id
|
||||
}) | indent(6) | trim }}
|
||||
{%- if hasHint %}
|
||||
{{ usaHint({
|
||||
id: itemHintId,
|
||||
classes: 'govuk-checkboxes__hint',
|
||||
classes: 'usa-checkbox__label-description',
|
||||
attributes: item.hint.attributes,
|
||||
html: item.hint.html,
|
||||
text: item.hint.text
|
||||
@@ -85,7 +85,7 @@
|
||||
{%- endif %}
|
||||
</div>
|
||||
{% if item.conditional %}
|
||||
<div class="govuk-checkboxes__conditional{% if not item.checked %} govuk-checkboxes__conditional--hidden{% endif %}" id="{{ conditionalId }}">
|
||||
<div class="usa-checkbox__conditional{% if not item.checked %} display-none{% endif %}" id="{{ conditionalId }}">
|
||||
{{ item.conditional.html | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
{% from "components/components/error-message/macro.njk" import usaErrorMessage -%}
|
||||
{% from "components/components/fieldset/macro.njk" import govukFieldset %}
|
||||
{% from "components/components/hint/macro.njk" import usaHint %}
|
||||
{% from "components/components/radio-label/macro.njk" import usaRadioLabel %}
|
||||
{% from "components/components/label/macro.njk" import usaLabel %}
|
||||
|
||||
|
||||
{#- Copied from https://github.com/alphagov/govuk-frontend/blob/v2.13.0/src/components/checkboxes/template.njk
|
||||
Changes:
|
||||
- `formGroup` option to control whether or not the checkboxes are wrapped with a `usa-form-group` class
|
||||
- `classes` option added to `item` allow custom classes on the `.govuk-checkboxes__item` element
|
||||
- `classes` option added to `item.hint` allow custom classes on the `.usa-hint` element (added to GOVUK Frontend in v3.5.0 - remove when we update)
|
||||
- `asList` option added the root `params` object to allow setting of the `.govuk-checkboxes` and `.govuk-checkboxes__item` element types
|
||||
- `children` option added to `item` allowing the sending in of prerendered child checkboxes (allowing the creation of tree structures through recursion) -#}
|
||||
{#- Updated from GOV.UK components to USWDS patterns
|
||||
Changed from original GOV.UK template:
|
||||
- Uses USWDS checkbox classes (usa-checkbox, usa-checkbox__input, usa-checkbox__label)
|
||||
- Conditional content uses display-none utility class instead of govuk-specific classes
|
||||
- Label uses usaLabel macro instead of radio label
|
||||
- Hint text uses usa-checkbox__label-description class
|
||||
- Maintains all original functionality including conditional reveals and nested checkboxes -#}
|
||||
{#- If an id 'prefix' is not passed, fall back to using the name attribute
|
||||
instead. We need this for error messages and hints as well -#}
|
||||
{% set idPrefix = params.idPrefix if params.idPrefix else params.name %}
|
||||
@@ -92,17 +92,17 @@
|
||||
{%- if item.conditional %} data-aria-controls="{{ conditionalId }}"{% endif -%}
|
||||
{%- if itemDescribedBy %} aria-describedby="{{ itemDescribedBy }}"{% endif -%}
|
||||
{%- for attribute, value in item.attributes %} {{ attribute }}="{{ value }}"{% endfor -%}>
|
||||
{{ usaRadioLabel({
|
||||
{{ usaLabel({
|
||||
html: item.html,
|
||||
text: item.text,
|
||||
classes: (' ' + item.label.classes if item.label.classes),
|
||||
classes: 'usa-checkbox__label' + (' ' + item.label.classes if item.label.classes),
|
||||
attributes: item.label.attributes,
|
||||
for: id
|
||||
}) | indent(6) | trim }}
|
||||
{%- if hasHint %}
|
||||
{{ usaHint({
|
||||
id: itemHintId,
|
||||
classes: 'govuk-checkboxes__hint' + (' ' + item.hint.classes if item.hint.classes),
|
||||
classes: 'usa-checkbox__label-description' + (' ' + item.hint.classes if item.hint.classes),
|
||||
attributes: item.hint.attributes,
|
||||
html: item.hint.html,
|
||||
text: item.hint.text
|
||||
@@ -112,14 +112,14 @@
|
||||
{{ item.children | safe }}
|
||||
{%- endif %}
|
||||
{% if params.asList and item.conditional %}
|
||||
<div class="govuk-checkboxes__conditional{% if not item.checked %} govuk-checkboxes__conditional--hidden{% endif %}" id="{{ conditionalId }}">
|
||||
<div class="usa-checkbox__conditional{% if not item.checked %} display-none{% endif %}" id="{{ conditionalId }}">
|
||||
{{ item.conditional.html | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{%- if item.after %}{{ item.after }}{% endif -%}
|
||||
</{{ groupItemElement }}>
|
||||
{% if not params.asList and item.conditional %}
|
||||
<div class="govuk-checkboxes__conditional{% if not item.checked %} govuk-checkboxes__conditional--hidden{% endif %}" id="{{ conditionalId }}">
|
||||
<div class="usa-checkbox__conditional{% if not item.checked %} display-none{% endif %}" id="{{ conditionalId }}">
|
||||
{{ item.conditional.html | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 326 KiB After Width: | Height: | Size: 325 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 938 KiB After Width: | Height: | Size: 931 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 227 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
@@ -63,10 +63,7 @@ def test_organization_page_shows_all_organizations(
|
||||
assert normalize_spaces(archived.text) == "- archived"
|
||||
assert normalize_spaces(archived.parent.text) == "Test 2 - archived 2 live services"
|
||||
|
||||
assert (
|
||||
normalize_spaces(page.select_one("a.usa-button").text)
|
||||
== "New organization"
|
||||
)
|
||||
assert normalize_spaces(page.select_one("a.usa-button").text) == "New organization"
|
||||
get_organizations.assert_called_once_with()
|
||||
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ describe('Collapsible fieldset', () => {
|
||||
for (let num = start; num <= end; num++) {
|
||||
let id = `folder-permissions-${num}`;
|
||||
|
||||
result += `<li class="govuk-checkboxes__item">
|
||||
<input class="govuk-checkboxes__input" id="${id}" name="folder-permissions" type="checkbox" value="${id}">
|
||||
<label class="usa-radio__label govuk-checkboxes__label" for="${id}">
|
||||
result += `<li class="usa-checkbox">
|
||||
<input class="usa-checkbox__input" id="${id}" name="folder-permissions" type="checkbox" value="${id}">
|
||||
<label class="usa-checkbox__label" for="${id}">
|
||||
Folder ${id}
|
||||
</label>
|
||||
</li>`;
|
||||
@@ -49,7 +49,7 @@ describe('Collapsible fieldset', () => {
|
||||
<div class="selection-summary" role="region" aria-live="polite"></div>
|
||||
</span>
|
||||
</legend>
|
||||
<ul class="govuk-checkboxes">
|
||||
<ul class="usa-checkbox-group">
|
||||
${_checkboxes(1, 10)}
|
||||
</ul>
|
||||
</fieldset>
|
||||
@@ -59,7 +59,7 @@ describe('Collapsible fieldset', () => {
|
||||
wrapper = document.querySelector('.selection-wrapper');
|
||||
formGroup = wrapper.querySelector('.usa-form-group');
|
||||
fieldset = formGroup.querySelector('fieldset');
|
||||
checkboxesContainer = fieldset.querySelector('.govuk-checkboxes');
|
||||
checkboxesContainer = fieldset.querySelector('.usa-checkbox-group');
|
||||
checkboxes = checkboxesContainer.querySelectorAll('input[type=checkbox]');
|
||||
|
||||
});
|
||||
@@ -323,7 +323,7 @@ describe('Collapsible fieldset', () => {
|
||||
const nestedCheckboxes = document.createElement('div');
|
||||
nestedCheckboxes.className = 'usa-form-group usa-form-group--nested';
|
||||
nestedCheckboxes.innerHTML = _checkboxes(11, 20);
|
||||
checkboxesContainer.querySelector('.govuk-checkboxes__item').appendChild(nestedCheckboxes);
|
||||
checkboxesContainer.querySelector('.usa-checkbox').appendChild(nestedCheckboxes);
|
||||
|
||||
// start module
|
||||
window.GOVUK.modules.start();
|
||||
|
||||
9
urls.js
9
urls.js
@@ -58,6 +58,15 @@ const routes = {
|
||||
label: 'Team Members',
|
||||
path: '/services/e6de050d-bd56-4f49-b44b-cb789c4f79fd/users',
|
||||
},
|
||||
{
|
||||
label: 'Invite User',
|
||||
path: '/services/e6de050d-bd56-4f49-b44b-cb789c4f79fd/users/invite',
|
||||
},
|
||||
// Platform admin pages with checkboxes
|
||||
{
|
||||
label: 'Platform Admin Live Services',
|
||||
path: '/platform-admin/live-services',
|
||||
},
|
||||
],
|
||||
|
||||
// Using Notify section
|
||||
|
||||
Reference in New Issue
Block a user