Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UAT Release #2333

Merged
merged 16 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/assets/styles/overrides/_all.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import "button";
@import "checkboxes";
@import "fieldset";
@import "file-upload";
@import "form-group";
@import "form-input";
Expand Down
11 changes: 11 additions & 0 deletions core/assets/styles/overrides/_fieldset.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fieldset {
.govuk-fieldset__legend--xl {
margin-bottom: 30px;
}

@media (min-width: 40.0625em) {
.govuk-fieldset__legend--xl {
margin-bottom: 50px;
}
}
}
26 changes: 26 additions & 0 deletions core/common/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
from crispy_forms_gds.choices import Choice
from crispy_forms_gds.layout import (
Div,
Fieldset,
HTML,
Layout,
Size,
Submit,
)
from django import forms
Expand Down Expand Up @@ -62,6 +64,30 @@ def get_layout_actions(self):
]


class FieldsetForm(BaseForm):
"""This is a suitable layout for a single question form. By using a
<fieldset> and <legend> it ensures that related inputs are grouped together
with a common label to enable users to easily identify the group, as
covered by WCAG Technique H71.
"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.helper.layout = Layout(
Fieldset(
*self.get_layout_fields(),
legend=self.get_title(),
legend_size=Size.EXTRA_LARGE,
legend_tag="h1",
),
Div(
*self.get_layout_actions(),
css_class="govuk-button-group",
),
)


class MultipleFileInput(forms.ClearableFileInput):
allow_multiple_selected = True

Expand Down
15 changes: 13 additions & 2 deletions exporter/applications/forms/hcsat.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from crispy_forms_gds.helper import FormHelper
from crispy_forms_gds.layout import Field, Layout, Submit, HTML
from crispy_forms_gds.layout import Field, Fieldset, Layout, Size, Submit, HTML
from django.urls import reverse_lazy
from django import forms

from core.forms.layouts import StarRadioSelect


class HCSATminiform(forms.Form):
class Layout:
TITLE = "Overall, how would you rate your experience with the 'apply for a standard individual export licence (SIEL)' service today?"

RECOMMENDATION_CHOICES = [
("VERY_DISSATISFIED", "Very dissatisfied"),
("DISSATISFIED", "Dissatisfied"),
Expand All @@ -23,11 +26,19 @@ class HCSATminiform(forms.Form):
error_messages={"required": "Star rating is required"},
)

def get_title(self):
return self.Layout.TITLE

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
StarRadioSelect("satisfaction_rating"),
Fieldset(
StarRadioSelect("satisfaction_rating"),
legend=self.get_title(),
legend_size=Size.MEDIUM,
legend_tag="h2",
),
Submit("submit", "Submit and continue"),
)

Expand Down
33 changes: 17 additions & 16 deletions exporter/applications/forms/parties.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from core.helpers import remove_non_printable_characters
from crispy_forms_gds.choices import Choice
from crispy_forms_gds.helper import FormHelper
from crispy_forms_gds.layout import Layout, Submit, HTML
from crispy_forms_gds.layout import Fieldset, Layout, Size, Submit, HTML
from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import MaxLengthValidator, URLValidator
from django.urls import reverse_lazy

from core.common.forms import BaseForm
from core.common.forms import BaseForm, FieldsetForm
from core.forms.layouts import ConditionalRadios, ConditionalRadiosQuestion
from core.forms.widgets import Autocomplete
from exporter.core.constants import CaseTypes, FileUploadFileTypes
Expand Down Expand Up @@ -133,10 +133,9 @@ def new_party_form_group(request, application, strings, back_url, clearance_opti
return FormGroup(forms)


class PartyReuseForm(BaseForm):
class PartyReuseForm(FieldsetForm):
class Layout:
TITLE = "Do you want to reuse an existing party?"
TITLE_AS_LABEL_FOR = "reuse_party"

reuse_party = forms.ChoiceField(
choices=(
Expand All @@ -154,7 +153,7 @@ def get_layout_fields(self):
return ("reuse_party",)


class PartySubTypeSelectForm(BaseForm):
class PartySubTypeSelectForm(FieldsetForm):
"""
This form needs to be instantiated with a Layout.TITLE for the type of party whose data is being set
as per the BaseForm.
Expand Down Expand Up @@ -200,13 +199,11 @@ def clean(self):
class EndUserSubTypeSelectForm(PartySubTypeSelectForm):
class Layout:
TITLE = "Select the type of end user"
TITLE_AS_LABEL_FOR = "sub_type"


class ConsigneeSubTypeSelectForm(PartySubTypeSelectForm):
class Layout:
TITLE = "Select the type of consignee"
TITLE_AS_LABEL_FOR = "sub_type"


class PartyNameForm(BaseForm):
Expand Down Expand Up @@ -395,15 +392,19 @@ def __init__(self, *args, **kwargs):

self.helper = FormHelper()
self.helper.layout = Layout(
HTML.h1(self.title),
HTML.p(self.text_p1),
HTML.p(self.text_p2),
HTML.p(self.text_p3),
HTML.p(self.text_p4),
ConditionalRadios(
"end_user_document_available",
"Yes",
ConditionalRadiosQuestion("No", "end_user_document_missing_reason"),
Fieldset(
HTML.p(self.text_p1),
HTML.p(self.text_p2),
HTML.p(self.text_p3),
HTML.p(self.text_p4),
ConditionalRadios(
"end_user_document_available",
"Yes",
ConditionalRadiosQuestion("No", "end_user_document_missing_reason"),
),
legend=self.title,
legend_size=Size.EXTRA_LARGE,
legend_tag="h1",
),
Submit("submit", "Continue"),
)
Expand Down
5 changes: 4 additions & 1 deletion exporter/applications/views/goods/goods.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,10 @@ def get_product_type(self):

def get_context_data(self, form, **kwargs):
context = super().get_context_data(form, **kwargs)
context["title"] = form.title
if hasattr(form, "Layout") and hasattr(form.Layout, "TITLE"):
context["title"] = form.Layout.TITLE
else:
context["title"] = form.title
# The back_link_url is used for the first form in the sequence. For subsequent forms,
# the wizard automatically generates the back link to the previous form.
context["back_link_url"] = reverse("applications:goods", kwargs={"pk": self.kwargs["pk"]})
Expand Down
6 changes: 3 additions & 3 deletions exporter/core/organisation/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from crispy_forms_gds.layout import HTML

from core.common.forms import BaseForm, TextChoice
from core.common.forms import BaseForm, FieldsetForm, TextChoice
from exporter.core.services import get_countries
from .validators import validate_phone
from exporter.core.organisation.services import validate_registration_number
Expand All @@ -27,7 +27,7 @@ def get_layout_fields(self):
return ()


class RegistrationTypeForm(BaseForm):
class RegistrationTypeForm(FieldsetForm):
class Layout:
TITLE = "Select the type of organisation"

Expand Down Expand Up @@ -58,7 +58,7 @@ def get_layout_fields(self):
return ("type",)


class RegistrationUKBasedForm(BaseForm):
class RegistrationUKBasedForm(FieldsetForm):
class Layout:
TITLE = "Where is your organisation based?"

Expand Down
20 changes: 10 additions & 10 deletions exporter/goods/forms/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
)
from core.forms.utils import coerce_str_to_bool

from core.common.forms import BaseForm
from core.common.forms import BaseForm, FieldsetForm
from exporter.core.forms import CustomErrorDateInputField
from exporter.core.services import (
get_control_list_entries,
Expand Down Expand Up @@ -52,7 +52,7 @@ def get_layout_fields(self):
)


class ProductControlListEntryForm(BaseForm):
class ProductControlListEntryForm(FieldsetForm):
class Layout:
TITLE = "Do you know the product's control list entry?"

Expand Down Expand Up @@ -120,7 +120,7 @@ def clean(self):
return cleaned_data


class ProductPVGradingForm(BaseForm):
class ProductPVGradingForm(FieldsetForm):
class Layout:
TITLE = "Does the product have a government security grading or classification?"

Expand Down Expand Up @@ -148,7 +148,7 @@ def get_layout_fields(self):
)


class ProductPVGradingDetailsForm(BaseForm):
class ProductPVGradingDetailsForm(FieldsetForm):
class Layout:
TITLE = "What is the security grading or classification?"

Expand Down Expand Up @@ -275,7 +275,7 @@ def clean(self):
return cleaned_data


class ProductDocumentAvailabilityForm(BaseForm):
class ProductDocumentAvailabilityForm(FieldsetForm):
class Layout:
TITLE = "Do you have a document that shows what your product is and what it's designed to do?"

Expand Down Expand Up @@ -324,7 +324,7 @@ def clean(self):
return cleaned_data


class ProductDocumentSensitivityForm(BaseForm):
class ProductDocumentSensitivityForm(FieldsetForm):
class Layout:
TITLE = "Is the document rated above Official-sensitive?"

Expand Down Expand Up @@ -354,7 +354,7 @@ def get_layout_fields(self):
)


class ProductDocumentUploadForm(BaseForm):
class ProductDocumentUploadForm(FieldsetForm):
class Layout:
TITLE = "Upload a document that shows what your product is designed to do"

Expand Down Expand Up @@ -404,7 +404,7 @@ def get_layout_fields(self):
return layout_fields


class ProductOnwardExportedForm(BaseForm):
class ProductOnwardExportedForm(FieldsetForm):
class Layout:
TITLE = "Is the product going to any ultimate end-users?"

Expand All @@ -431,7 +431,7 @@ def get_layout_fields(self):
)


class ProductOnwardAlteredProcessedForm(BaseForm):
class ProductOnwardAlteredProcessedForm(FieldsetForm):
class Layout:
TITLE = "Will the item be altered or processed before it is exported again?"

Expand Down Expand Up @@ -482,7 +482,7 @@ def clean(self):
return cleaned_data


class ProductOnwardIncorporatedForm(BaseForm):
class ProductOnwardIncorporatedForm(FieldsetForm):
class Layout:
TITLE = "Will the product be incorporated into another item before it is onward exported?"

Expand Down
14 changes: 7 additions & 7 deletions exporter/goods/forms/firearms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
)
from core.forms.utils import coerce_str_to_bool

from core.common.forms import BaseForm, TextChoice
from core.common.forms import BaseForm, FieldsetForm, TextChoice
from exporter.core.forms import (
CustomErrorDateInputField,
PotentiallyUnsafeClearableFileInput,
Expand Down Expand Up @@ -100,7 +100,7 @@ def get_layout_fields(self):
return ("calibre",)


class FirearmReplicaForm(BaseForm):
class FirearmReplicaForm(FieldsetForm):
class Layout:
TITLE = "Is the product a replica firearm?"

Expand Down Expand Up @@ -192,7 +192,7 @@ def get_layout_fields(self):
)


class FirearmRegisteredFirearmsDealerForm(BaseForm):
class FirearmRegisteredFirearmsDealerForm(FieldsetForm):
class Layout:
TITLE = "Are you a registered firearms dealer?"

Expand Down Expand Up @@ -267,7 +267,7 @@ def get_layout_fields(self):
)


class FirearmFirearmAct1968Form(BaseForm):
class FirearmFirearmAct1968Form(FieldsetForm):
class Layout:
TITLE = "Which section of the Firearms Act 1968 is the product covered by?"

Expand Down Expand Up @@ -462,7 +462,7 @@ def get_layout_fields(self):
return ("is_covered_by_section_5",)


class FirearmMadeBefore1938Form(BaseForm):
class FirearmMadeBefore1938Form(FieldsetForm):
class Layout:
TITLE = "Was the product made before 1938?"

Expand Down Expand Up @@ -503,7 +503,7 @@ def get_layout_fields(self):
return ("year_of_manufacture",)


class FirearmIsDeactivatedForm(BaseForm):
class FirearmIsDeactivatedForm(FieldsetForm):
class Layout:
TITLE = "Has the product been deactivated?"

Expand Down Expand Up @@ -599,7 +599,7 @@ def clean(self):
return cleaned_data


class FirearmSerialIdentificationMarkingsForm(BaseForm):
class FirearmSerialIdentificationMarkingsForm(FieldsetForm):
class Layout:
TITLE = "Will each product have a serial number or other identification marking?"

Expand Down
Loading
Loading