Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
dave-kennedy-ecs committed Jan 3, 2025
2 parents 560a07f + e7e3c72 commit d2f1d1f
Show file tree
Hide file tree
Showing 66 changed files with 1,194 additions and 842 deletions.
46 changes: 46 additions & 0 deletions src/registrar/assets/src/js/getgov-admin/domain-request-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -629,12 +629,58 @@ export function initRejectedEmail() {
});
}


/**
* A function that handles the suborganzation and requested suborganization fields and buttons.
* - Fieldwise: Hooks to the sub_organization, suborganization_city, and suborganization_state_territory fields.
* On change, this function checks if any of these fields are not empty:
* sub_organization, suborganization_city, and suborganization_state_territory.
* If they aren't, then we show the "clear" button. If they are, then we hide it because we don't need it.
*
* - Buttonwise: Hooks to the #clear-requested-suborganization button.
* On click, this will clear the input value of sub_organization, suborganization_city, and suborganization_state_territory.
*/
function handleSuborgFieldsAndButtons() {
const requestedSuborganizationField = document.getElementById("id_requested_suborganization");
const suborganizationCity = document.getElementById("id_suborganization_city");
const suborganizationStateTerritory = document.getElementById("id_suborganization_state_territory");
const rejectButton = document.querySelector("#clear-requested-suborganization");

// Ensure that every variable is present before proceeding
if (!requestedSuborganizationField || !suborganizationCity || !suborganizationStateTerritory || !rejectButton) {
console.warn("handleSuborganizationSelection() => Could not find required fields.")
return;
}

function handleRejectButtonVisibility() {
if (requestedSuborganizationField.value || suborganizationCity.value || suborganizationStateTerritory.value) {
showElement(rejectButton);
}else {
hideElement(rejectButton)
}
}

function handleRejectButton() {
// Clear the text fields
requestedSuborganizationField.value = "";
suborganizationCity.value = "";
suborganizationStateTerritory.value = "";
// Update button visibility after clearing
handleRejectButtonVisibility();
}
rejectButton.addEventListener("click", handleRejectButton)
requestedSuborganizationField.addEventListener("blur", handleRejectButtonVisibility);
suborganizationCity.addEventListener("blur", handleRejectButtonVisibility);
suborganizationStateTerritory.addEventListener("change", handleRejectButtonVisibility);
}

/**
* A function for dynamic DomainRequest fields
*/
export function initDynamicDomainRequestFields(){
const domainRequestPage = document.getElementById("domainrequest_form");
if (domainRequestPage) {
handlePortfolioSelection();
handleSuborgFieldsAndButtons();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ export function handlePortfolioSelection(
const portfolioUrbanizationField = document.querySelector(".field-portfolio_urbanization");
const portfolioUrbanization = portfolioUrbanizationField.querySelector(".readonly");
const portfolioJsonUrl = document.getElementById("portfolio_json_url")?.value || null;
// These requested suborganization fields only exist on the domain request page
const rejectSuborganizationButton = document.querySelector("#clear-requested-suborganization");
const requestedSuborganizationFieldInput = document.getElementById("id_requested_suborganization");
const suborganizationCityInput = document.getElementById("id_suborganization_city");
const suborganizationStateTerritoryInput = document.getElementById("id_suborganization_state_territory");

// Global var to track page load
let isPageLoading = true;

/**
Expand Down Expand Up @@ -469,11 +476,28 @@ export function handlePortfolioSelection(
if (requestedSuborganizationField) showElement(requestedSuborganizationField);
if (suborganizationCity) showElement(suborganizationCity);
if (suborganizationStateTerritory) showElement(suborganizationStateTerritory);

// == LOGIC FOR THE DOMAIN REQUEST PAGE == //
// Handle rejectSuborganizationButton (display of the clear requested suborg button).
// Basically, this button should only be visible when we have data for suborg, city, and state_territory.
// The function handleSuborgFieldsAndButtons() in domain-request-form.js handles doing this same logic
// but on field input for city, state_territory, and the suborg field.
// If it doesn't exist, don't do anything.
if (rejectSuborganizationButton){
if (requestedSuborganizationFieldInput?.value || suborganizationCityInput?.value || suborganizationStateTerritoryInput?.value) {
showElement(rejectSuborganizationButton);
}else {
hideElement(rejectSuborganizationButton);
}
}
} else {
// Hide suborganization request fields if suborganization is selected
if (requestedSuborganizationField) hideElement(requestedSuborganizationField);
if (suborganizationCity) hideElement(suborganizationCity);
if (suborganizationStateTerritory) hideElement(suborganizationStateTerritory);
if (suborganizationStateTerritory) hideElement(suborganizationStateTerritory);

// == LOGIC FOR THE DOMAIN REQUEST PAGE == //
if (rejectSuborganizationButton) hideElement(rejectSuborganizationButton);
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/registrar/assets/src/sass/_theme/_admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,16 @@ html[data-theme="dark"] {
color: var(--primary-fg);
}

// Reset the USWDS styles for alerts
@include at-media(desktop) {
.dashboard .usa-alert__body--widescreen {
padding-left: 4rem !important;
}

.dashboard .usa-alert__body--widescreen::before {
left: 1.5rem !important;
}
}

#branding h1,
h1, h2, h3,
Expand Down
41 changes: 27 additions & 14 deletions src/registrar/assets/src/sass/_theme/_alerts.scss
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
@use "uswds-core" as *;
@use "base" as *;

// Fixes some font size disparities with the Figma
// for usa-alert alert elements
.usa-alert {
.usa-alert__heading.larger-font-sizing {
font-size: units(3);
}
}

.usa-alert__text.measure-none {
max-width: measure(none);
}
/*----------------
Alert Layout
-----------------*/

// The icon was off center for some reason
// Fixes that issue
@media (min-width: 64em){
@include at-media(desktop) {
// NOTE: !important is used because _font.scss overrides this
.usa-alert__body {
max-width: $widescreen-max-width !important;
}
.usa-alert--warning{
.usa-alert__body::before {
left: 1rem !important;
Expand All @@ -24,13 +21,29 @@
.usa-alert__body.margin-left-1 {
margin-left: 0.5rem!important;
}

.usa-alert__body--widescreen::before {
left: 4rem !important;
}
.usa-alert__body--widescreen {
padding-left: 7rem!important;
}
}

// NOTE: !important is used because _font.scss overrides this
.usa-alert__body--widescreen {
max-width: $widescreen-max-width !important;
/*----------------
Alert Fonts
-----------------*/
// Fixes some font size disparities with the Figma
// for usa-alert alert elements
.usa-alert {
.usa-alert__heading.larger-font-sizing {
font-size: 1.5rem;
}
}

/*----------------
Alert Coloring
-----------------*/
.usa-site-alert--hot-pink {
.usa-alert {
background-color: $hot-pink;
Expand Down
15 changes: 15 additions & 0 deletions src/registrar/assets/src/sass/_theme/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
@use "cisa_colors" as *;

$widescreen-max-width: 1920px;
$widescreen-x-padding: 4.5rem;

$hot-pink: #FFC3F9;

/* Styles for making visible to screen reader / AT users only. */
Expand Down Expand Up @@ -253,6 +255,15 @@ abbr[title] {
max-width: $widescreen-max-width;
}

// This is used in cases where we want to align content to widescreen margins
// but we don't want the content itself to have widescreen widths
@include at-media(desktop) {
.padding-x--widescreen {
padding-left: $widescreen-x-padding !important;
padding-right: $widescreen-x-padding !important;
}
}

.margin-right-neg-4px {
margin-right: -4px;
}
Expand All @@ -267,3 +278,7 @@ abbr[title] {
height: 1.5em;
width: 1.5em;
}

.maxw-fit-content {
max-width: fit-content;
}
18 changes: 18 additions & 0 deletions src/registrar/assets/src/sass/_theme/_containers.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,21 @@
.usa-identifier__container--widescreen {
max-width: $widescreen-max-width !important;
}


// NOTE: !important is used because we are overriding default
// USWDS paddings in a few locations
@include at-media(desktop) {
.grid-container--widescreen {
padding-left: $widescreen-x-padding !important;
padding-right: $widescreen-x-padding !important;
}
}

// matches max-width to equal the max-width of .grid-container
// used to trick the eye into thinking we have left-aligned a
// regular grid-container within a widescreen (see instances
// where is_widescreen_centered is used in the html).
.max-width--grid-container {
max-width: 960px;
}
4 changes: 2 additions & 2 deletions src/registrar/assets/src/sass/_theme/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@
}
}
.usa-nav__secondary {
// I don't know why USWDS has this at 2 rem, which puts it out of alignment
right: 3rem;
right: 1rem;
padding-right: $widescreen-x-padding;
color: color('white');
bottom: 4.3rem;
.usa-nav-link,
Expand Down
2 changes: 1 addition & 1 deletion src/registrar/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@
"registrar.context_processors.org_user_status",
"registrar.context_processors.add_path_to_context",
"registrar.context_processors.portfolio_permissions",
"registrar.context_processors.is_widescreen_mode",
"registrar.context_processors.is_widescreen_centered",
],
},
},
Expand Down
26 changes: 8 additions & 18 deletions src/registrar/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,31 +109,21 @@ def portfolio_permissions(request):
return portfolio_context


def is_widescreen_mode(request):
widescreen_paths = [] # If this list is meant to include specific paths, populate it.
portfolio_widescreen_paths = [
def is_widescreen_centered(request):
include_paths = [
"/domains/",
"/requests/",
"/request/",
"/no-organization-requests/",
"/no-organization-domains/",
"/domain-request/",
"/members/",
]
# widescreen_paths can be a bear as it trickles down sub-urls. exclude_paths gives us a way out.
exclude_paths = [
"/domains/edit",
"members/new-member/",
]

# Check if the current path matches a widescreen path or the root path.
is_widescreen = any(path in request.path for path in widescreen_paths) or request.path == "/"
is_excluded = any(exclude_path in request.path for exclude_path in exclude_paths)

# Check if the user is an organization user and the path matches portfolio paths.
is_portfolio_widescreen = (
hasattr(request.user, "is_org_user")
and request.user.is_org_user(request)
and any(path in request.path for path in portfolio_widescreen_paths)
and not any(exclude_path in request.path for exclude_path in exclude_paths)
)
# Check if the current path matches a path in included_paths or the root path.
is_widescreen_centered = any(path in request.path for path in include_paths) or request.path == "/"

# Return a dictionary with the widescreen mode status.
return {"is_widescreen_mode": is_widescreen or is_portfolio_widescreen}
return {"is_widescreen_centered": is_widescreen_centered and not is_excluded}
17 changes: 16 additions & 1 deletion src/registrar/forms/domain_request_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from registrar.templatetags.url_helpers import public_site_url
from registrar.utility.enums import ValidationReturnType
from registrar.utility.constants import BranchChoices
from django.core.exceptions import ValidationError

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -78,6 +79,20 @@ def clean_sub_organization(self):
# Otherwise just return the suborg as normal
return self.cleaned_data.get("sub_organization")

def clean_requested_suborganization(self):
name = self.cleaned_data.get("requested_suborganization")
if (
name
and Suborganization.objects.filter(
name__iexact=name, portfolio=self.domain_request.portfolio, name__isnull=False, portfolio__isnull=False
).exists()
):
raise ValidationError(
"This suborganization already exists. "
"Choose a new name, or select it directly if you would like to use it."
)
return name

def full_clean(self):
"""Validation logic to remove the custom suborganization value before clean is triggered.
Without this override, the form will throw an 'invalid option' error."""
Expand Down Expand Up @@ -114,7 +129,7 @@ def clean(self):
if requesting_entity_is_suborganization == "True":
if is_requesting_new_suborganization:
# Validate custom suborganization fields
if not cleaned_data.get("requested_suborganization"):
if not cleaned_data.get("requested_suborganization") and "requested_suborganization" not in self.errors:
self.add_error("requested_suborganization", "Enter the name of your suborganization.")
if not cleaned_data.get("suborganization_city"):
self.add_error("suborganization_city", "Enter the city where your suborganization is located.")
Expand Down
Loading

0 comments on commit d2f1d1f

Please sign in to comment.