Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into nl/3074-responsive-la…
Browse files Browse the repository at this point in the history
…youts-widescreen
  • Loading branch information
CocoByte committed Dec 19, 2024
2 parents 7e4d8e3 + f475f4a commit 8b80110
Show file tree
Hide file tree
Showing 30 changed files with 1,449 additions and 405 deletions.
2 changes: 1 addition & 1 deletion ops/manifests/manifest-ms.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ applications:
# Tell Django where it is being hosted
DJANGO_BASE_URL: https://getgov-ms.app.cloud.gov
# Tell Django how much stuff to log
DJANGO_LOG_LEVEL: INFO
DJANGO_LOG_LEVEL: DEBUG
# default public site location
GETGOV_PUBLIC_SITE_URL: https://get.gov
# Flag to disable/enable features in prod environments
Expand Down
4 changes: 3 additions & 1 deletion src/epplibwrapper/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ class RegistryError(Exception):
- 2501 - 2502 Something malicious or abusive may have occurred
"""

def __init__(self, *args, code=None, **kwargs):
def __init__(self, *args, code=None, note="", **kwargs):
super().__init__(*args, **kwargs)
self.code = code
# note is a string that can be used to provide additional context
self.note = note

def should_retry(self):
return self.code == ErrorCode.COMMAND_FAILED
Expand Down
223 changes: 218 additions & 5 deletions src/registrar/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ class Meta:
fields = "__all__"
widgets = {
"other_contacts": NoAutocompleteFilteredSelectMultiple("other_contacts", False),
"portfolio": AutocompleteSelectWithPlaceholder(
DomainInformation._meta.get_field("portfolio"), admin.site, attrs={"data-placeholder": "---------"}
),
"sub_organization": AutocompleteSelectWithPlaceholder(
DomainInformation._meta.get_field("sub_organization"),
admin.site,
attrs={"data-placeholder": "---------", "ajax-url": "get-suborganization-list-json"},
),
}


Expand All @@ -231,6 +239,14 @@ class Meta:
fields = "__all__"
widgets = {
"other_contacts": NoAutocompleteFilteredSelectMultiple("other_contacts", False),
"portfolio": AutocompleteSelectWithPlaceholder(
DomainInformation._meta.get_field("portfolio"), admin.site, attrs={"data-placeholder": "---------"}
),
"sub_organization": AutocompleteSelectWithPlaceholder(
DomainInformation._meta.get_field("sub_organization"),
admin.site,
attrs={"data-placeholder": "---------", "ajax-url": "get-suborganization-list-json"},
),
}


Expand Down Expand Up @@ -1523,6 +1539,70 @@ def converted_generic_org_type(self, obj):

orderable_fk_fields = [("domain", "name")]

# Define methods to display fields from the related portfolio
def portfolio_senior_official(self, obj) -> Optional[SeniorOfficial]:
return obj.portfolio.senior_official if obj.portfolio and obj.portfolio.senior_official else None

portfolio_senior_official.short_description = "Senior official" # type: ignore

def portfolio_organization_type(self, obj):
return (
DomainRequest.OrganizationChoices.get_org_label(obj.portfolio.organization_type)
if obj.portfolio and obj.portfolio.organization_type
else "-"
)

portfolio_organization_type.short_description = "Organization type" # type: ignore

def portfolio_federal_type(self, obj):
return (
BranchChoices.get_branch_label(obj.portfolio.federal_type)
if obj.portfolio and obj.portfolio.federal_type
else "-"
)

portfolio_federal_type.short_description = "Federal type" # type: ignore

def portfolio_organization_name(self, obj):
return obj.portfolio.organization_name if obj.portfolio else ""

portfolio_organization_name.short_description = "Organization name" # type: ignore

def portfolio_federal_agency(self, obj):
return obj.portfolio.federal_agency if obj.portfolio else ""

portfolio_federal_agency.short_description = "Federal agency" # type: ignore

def portfolio_state_territory(self, obj):
return obj.portfolio.state_territory if obj.portfolio else ""

portfolio_state_territory.short_description = "State, territory, or military post" # type: ignore

def portfolio_address_line1(self, obj):
return obj.portfolio.address_line1 if obj.portfolio else ""

portfolio_address_line1.short_description = "Address line 1" # type: ignore

def portfolio_address_line2(self, obj):
return obj.portfolio.address_line2 if obj.portfolio else ""

portfolio_address_line2.short_description = "Address line 2" # type: ignore

def portfolio_city(self, obj):
return obj.portfolio.city if obj.portfolio else ""

portfolio_city.short_description = "City" # type: ignore

def portfolio_zipcode(self, obj):
return obj.portfolio.zipcode if obj.portfolio else ""

portfolio_zipcode.short_description = "Zip code" # type: ignore

def portfolio_urbanization(self, obj):
return obj.portfolio.urbanization if obj.portfolio else ""

portfolio_urbanization.short_description = "Urbanization" # type: ignore

# Filters
list_filter = [GenericOrgFilter]

Expand All @@ -1535,18 +1615,38 @@ def converted_generic_org_type(self, obj):
fieldsets = [
(
None,
{
"fields": [
"domain_request",
"notes",
]
},
),
(
"Requested by",
{
"fields": [
"portfolio",
"sub_organization",
"creator",
"domain_request",
"notes",
]
},
),
(".gov domain", {"fields": ["domain"]}),
("Contacts", {"fields": ["senior_official", "other_contacts", "no_other_contacts_rationale"]}),
(
"Contacts",
{
"fields": [
"senior_official",
"portfolio_senior_official",
"other_contacts",
"no_other_contacts_rationale",
"cisa_representative_first_name",
"cisa_representative_last_name",
"cisa_representative_email",
]
},
),
("Background info", {"fields": ["anything_else"]}),
(
"Type of organization",
Expand Down Expand Up @@ -1595,10 +1695,58 @@ def converted_generic_org_type(self, obj):
],
},
),
# the below three sections are for portfolio fields
(
"Type of organization",
{
"fields": [
"portfolio_organization_type",
"portfolio_federal_type",
]
},
),
(
"Organization name and mailing address",
{
"fields": [
"portfolio_organization_name",
"portfolio_federal_agency",
]
},
),
(
"Show details",
{
"classes": ["collapse--dgfieldset"],
"description": "Extends organization name and mailing address",
"fields": [
"portfolio_state_territory",
"portfolio_address_line1",
"portfolio_address_line2",
"portfolio_city",
"portfolio_zipcode",
"portfolio_urbanization",
],
},
),
]

# Readonly fields for analysts and superusers
readonly_fields = ("other_contacts", "is_election_board")
readonly_fields = (
"portfolio_senior_official",
"portfolio_organization_type",
"portfolio_federal_type",
"portfolio_organization_name",
"portfolio_federal_agency",
"portfolio_state_territory",
"portfolio_address_line1",
"portfolio_address_line2",
"portfolio_city",
"portfolio_zipcode",
"portfolio_urbanization",
"other_contacts",
"is_election_board",
)

# Read only that we'll leverage for CISA Analysts
analyst_readonly_fields = [
Expand Down Expand Up @@ -2575,7 +2723,72 @@ class DomainInformationInline(admin.StackedInline):
template = "django/admin/includes/domain_info_inline_stacked.html"
model = models.DomainInformation

# Define methods to display fields from the related portfolio
def portfolio_senior_official(self, obj) -> Optional[SeniorOfficial]:
return obj.portfolio.senior_official if obj.portfolio and obj.portfolio.senior_official else None

portfolio_senior_official.short_description = "Senior official" # type: ignore

def portfolio_organization_type(self, obj):
return (
DomainRequest.OrganizationChoices.get_org_label(obj.portfolio.organization_type)
if obj.portfolio and obj.portfolio.organization_type
else "-"
)

portfolio_organization_type.short_description = "Organization type" # type: ignore

def portfolio_federal_type(self, obj):
return (
BranchChoices.get_branch_label(obj.portfolio.federal_type)
if obj.portfolio and obj.portfolio.federal_type
else "-"
)

portfolio_federal_type.short_description = "Federal type" # type: ignore

def portfolio_organization_name(self, obj):
return obj.portfolio.organization_name if obj.portfolio else ""

portfolio_organization_name.short_description = "Organization name" # type: ignore

def portfolio_federal_agency(self, obj):
return obj.portfolio.federal_agency if obj.portfolio else ""

portfolio_federal_agency.short_description = "Federal agency" # type: ignore

def portfolio_state_territory(self, obj):
return obj.portfolio.state_territory if obj.portfolio else ""

portfolio_state_territory.short_description = "State, territory, or military post" # type: ignore

def portfolio_address_line1(self, obj):
return obj.portfolio.address_line1 if obj.portfolio else ""

portfolio_address_line1.short_description = "Address line 1" # type: ignore

def portfolio_address_line2(self, obj):
return obj.portfolio.address_line2 if obj.portfolio else ""

portfolio_address_line2.short_description = "Address line 2" # type: ignore

def portfolio_city(self, obj):
return obj.portfolio.city if obj.portfolio else ""

portfolio_city.short_description = "City" # type: ignore

def portfolio_zipcode(self, obj):
return obj.portfolio.zipcode if obj.portfolio else ""

portfolio_zipcode.short_description = "Zip code" # type: ignore

def portfolio_urbanization(self, obj):
return obj.portfolio.urbanization if obj.portfolio else ""

portfolio_urbanization.short_description = "Urbanization" # type: ignore

fieldsets = copy.deepcopy(list(DomainInformationAdmin.fieldsets))
readonly_fields = copy.deepcopy(DomainInformationAdmin.readonly_fields)
analyst_readonly_fields = copy.deepcopy(DomainInformationAdmin.analyst_readonly_fields)
autocomplete_fields = copy.deepcopy(DomainInformationAdmin.autocomplete_fields)

Expand Down Expand Up @@ -3121,7 +3334,7 @@ def do_delete_domain(self, request, obj):
except RegistryError as err:
# Using variables to get past the linter
message1 = f"Cannot delete Domain when in state {obj.state}"
message2 = "This subdomain is being used as a hostname on another domain"
message2 = f"This subdomain is being used as a hostname on another domain: {err.note}"
# Human-readable mappings of ErrorCodes. Can be expanded.
error_messages = {
# noqa on these items as black wants to reformat to an invalid length
Expand Down
13 changes: 13 additions & 0 deletions src/registrar/assets/src/js/getgov-admin/domain-form.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { handlePortfolioSelection } from './helpers-portfolio-dynamic-fields.js';

/**
* A function that appends target="_blank" to the domain_form buttons
*/
Expand Down Expand Up @@ -28,3 +30,14 @@ export function initDomainFormTargetBlankButtons() {
domainSubmitButton.addEventListener("mouseout", () => openInNewTab(domainFormElement, false));
}
}

/**
* A function for dynamic Domain fields
*/
export function initDynamicDomainFields(){
const domainPage = document.getElementById("domain_form");
if (domainPage) {
handlePortfolioSelection("#id_domain_info-0-portfolio",
"#id_domain_info-0-sub_organization");
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { handleSuborganizationFields } from './helpers-portfolio-dynamic-fields.js';
import { handlePortfolioSelection } from './helpers-portfolio-dynamic-fields.js';

/**
* A function for dynamic DomainInformation fields
*/
export function initDynamicDomainInformationFields(){
const domainInformationPage = document.getElementById("domaininformation_form");
if (domainInformationPage) {
handleSuborganizationFields();
}

// DomainInformation is embedded inside domain so this should fire there too
const domainPage = document.getElementById("domain_form");
if (domainPage) {
handleSuborganizationFields(portfolioDropdownSelector="#id_domain_info-0-portfolio", suborgDropdownSelector="#id_domain_info-0-sub_organization");
console.log("handling domain information page");
handlePortfolioSelection();
}
}
Loading

0 comments on commit 8b80110

Please sign in to comment.