diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index 90137c4af..93c92f1ca 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -74,6 +74,11 @@ urlpatterns = [ views.PortfolioOrganizationView.as_view(), name="organization", ), + path( + "senior-official/", + views.PortfolioSeniorOfficialView.as_view(), + name="senior-official", + ), path( "admin/logout/", RedirectView.as_view(pattern_name="logout", permanent=False), diff --git a/src/registrar/forms/portfolio.py b/src/registrar/forms/portfolio.py index 9362c7bbd..88ec8e3f7 100644 --- a/src/registrar/forms/portfolio.py +++ b/src/registrar/forms/portfolio.py @@ -4,7 +4,7 @@ import logging from django import forms from django.core.validators import RegexValidator -from ..models import DomainInformation, Portfolio +from ..models import DomainInformation, Portfolio, SeniorOfficial logger = logging.getLogger(__name__) @@ -67,3 +67,47 @@ class PortfolioOrgAddressForm(forms.ModelForm): self.fields[field_name].required = True self.fields["state_territory"].widget.attrs.pop("maxlength", None) self.fields["zipcode"].widget.attrs.pop("maxlength", None) + + +class PortfolioSeniorOfficialForm(forms.ModelForm): + """Form for updating the portfolio senior official.""" + + JOIN = "senior_official" + + class Meta: + model = SeniorOfficial + # TODO - add full name + fields = [ + "first_name", + "last_name", + "title", + "email", + ] + + # error_messages = { + # "address_line1": {"required": "Enter the street address of your organization."}, + # "city": {"required": "Enter the city where your organization is located."}, + # "state_territory": { + # "required": "Select the state, territory, or military post where your organization is located." + # }, + # } + widgets = { + # We need to set the required attributed for State/territory + # because for this fields we are creating an individual + # instance of the Select. For the other fields we use the for loop to set + # the class's required attribute to true. + "first_name": forms.TextInput, + "last_name": forms.TextInput, + "title": forms.TextInput, + "email": forms.TextInput, + } + + # the database fields have blank=True so ModelForm doesn't create + # required fields by default. Use this list in __init__ to mark each + # of these fields as required + required = ["first_name", "last_name", "title", "email"] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + for field_name in self.required: + self.fields[field_name].required = True diff --git a/src/registrar/templates/portfolio_organization_sidebar.html b/src/registrar/templates/portfolio_organization_sidebar.html index cfcdff3a8..cfbb30e91 100644 --- a/src/registrar/templates/portfolio_organization_sidebar.html +++ b/src/registrar/templates/portfolio_organization_sidebar.html @@ -13,7 +13,9 @@
+ Portfolio name: {{ portfolio }} +
+ + {% include 'portfolio_organization_sidebar.html' %} +Your senior official is a person within your organization who can authorize domain requests.
+ +The senior official for your organization can’t be updated here. To suggest an update, email help@get.gov
+ + {% if has_edit_org_portfolio_permission %} + {% include "includes/form_errors.html" with form=form %} + {% include "includes/required_fields.html" %} + + {% else %} ++ {{ portfolio.senior_official.get_formatted_name }} +
+ {% if form.city.value is not None %} + {% include "includes/input_read_only.html" with field=form.title %} + {% endif %} + {% if form.state_territory.value is not None %} + {% include "includes/input_read_only.html" with field=form.email %} + {% endif %} + {% endif %} + +