diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 93d0673f0..c662f91d7 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -1447,6 +1447,7 @@ class UserPortfolioPermissionAdmin(ListHeaderAdmin): search_help_text = "Search by first name, last name, email, or portfolio." change_form_template = "django/admin/user_portfolio_permission_change_form.html" + delete_confirmation_template = "django/admin/user_portfolio_permission_delete_confirmation.html" def get_roles(self, obj): readable_roles = obj.get_readable_roles() @@ -1790,6 +1791,7 @@ class PortfolioInvitationAdmin(BaseInvitationAdmin): autocomplete_fields = ["portfolio"] change_form_template = "django/admin/portfolio_invitation_change_form.html" + delete_confirmation_template = "django/admin/portfolio_invitation_delete_confirmation.html" # Select portfolio invitations to change -> Portfolio invitations def changelist_view(self, request, extra_context=None): @@ -3858,11 +3860,13 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin): # Using variables to get past the linter message1 = f"Cannot delete Domain when in state {obj.state}" message2 = f"This subdomain is being used as a hostname on another domain: {err.note}" + message3 = f"Command failed with note: {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 ErrorCode.OBJECT_STATUS_PROHIBITS_OPERATION: message1, ErrorCode.OBJECT_ASSOCIATION_PROHIBITS_OPERATION: message2, + ErrorCode.COMMAND_FAILED: message3, } message = "Cannot connect to the registry" diff --git a/src/registrar/assets/js/uswds-edited.js b/src/registrar/assets/js/uswds-edited.js index 9d4dd2e51..ae246b05c 100644 --- a/src/registrar/assets/js/uswds-edited.js +++ b/src/registrar/assets/js/uswds-edited.js @@ -5695,19 +5695,35 @@ const createHeaderButton = (header, headerName) => { buttonEl.setAttribute("tabindex", "0"); buttonEl.classList.add(SORT_BUTTON_CLASS); // ICON_SOURCE + // ---- END DOTGOV EDIT + // Change icons on sort, use source from arro_upward and arrow_downward + // buttonEl.innerHTML = Sanitizer.escapeHTML` + // + // + // + // + // + // + // + // + // + // + // + // `; buttonEl.innerHTML = Sanitizer.escapeHTML` - + - + `; + // ---- END DOTGOV EDIT header.appendChild(buttonEl); updateSortLabel(header, headerName); }; diff --git a/src/registrar/assets/src/js/getgov/domain-request-form.js b/src/registrar/assets/src/js/getgov/domain-request-form.js index d9b660a50..b49912fa4 100644 --- a/src/registrar/assets/src/js/getgov/domain-request-form.js +++ b/src/registrar/assets/src/js/getgov/domain-request-form.js @@ -2,11 +2,41 @@ import { submitForm } from './helpers.js'; export function initDomainRequestForm() { document.addEventListener('DOMContentLoaded', function() { - const button = document.getElementById("domain-request-form-submit-button"); - if (button) { - button.addEventListener("click", function () { - submitForm("submit-domain-request-form"); - }); - } + // These are the request steps in DomainRequestWizard, such as current_websites or review + initRequestStepCurrentWebsitesListener(); + initRequestStepReviewListener(); }); +} + +function initRequestStepReviewListener() { + const button = document.getElementById("domain-request-form-submit-button"); + if (button) { + button.addEventListener("click", function () { + submitForm("submit-domain-request-form"); + }); + } +} + +function initRequestStepCurrentWebsitesListener() { + //register-form-step + const addAnotherSiteButton = document.getElementById("submit-domain-request--site-button"); + if (addAnotherSiteButton) { + // Check for focus state in sessionStorage + const focusTarget = sessionStorage.getItem("lastFocusedElement"); + if (focusTarget) { + document.querySelector(focusTarget)?.focus(); + } + // Add form submit handler to store focus state + const form = document.querySelector("form"); + if (form) { + form.addEventListener("submit", () => { + const activeElement = document.activeElement; + if (activeElement) { + sessionStorage.setItem("lastFocusedElement", "#" + activeElement.id); + } + }); + } + // We only want to do this action once, so we clear out the session + sessionStorage.removeItem("lastFocusedElement"); + } } \ No newline at end of file diff --git a/src/registrar/assets/src/js/getgov/helpers.js b/src/registrar/assets/src/js/getgov/helpers.js index 7d1449bac..08be011c2 100644 --- a/src/registrar/assets/src/js/getgov/helpers.js +++ b/src/registrar/assets/src/js/getgov/helpers.js @@ -96,3 +96,14 @@ export function submitForm(form_id) { console.error("Form '" + form_id + "' not found."); } } + +/** + * Helper function to strip HTML tags + * THIS IS NOT SUITABLE FOR SANITIZING DANGEROUS STRINGS + */ +export function unsafeStripHtmlTags(input) { + const tempDiv = document.createElement("div"); + // NOTE: THIS IS NOT SUITABLE FOR SANITIZING DANGEROUS STRINGS + tempDiv.innerHTML = input; + return tempDiv.textContent || tempDiv.innerText || ""; +} diff --git a/src/registrar/assets/src/js/getgov/portfolio-member-page.js b/src/registrar/assets/src/js/getgov/portfolio-member-page.js index 95723fc7e..96961e5dc 100644 --- a/src/registrar/assets/src/js/getgov/portfolio-member-page.js +++ b/src/registrar/assets/src/js/getgov/portfolio-member-page.js @@ -18,7 +18,7 @@ export function initPortfolioNewMemberPageToggle() { const unique_id = `${member_type}-${member_id}`; let cancelInvitationButton = member_type === "invitedmember" ? "Cancel invitation" : "Remove member"; - wrapperDeleteAction.innerHTML = generateKebabHTML('remove-member', unique_id, cancelInvitationButton, `More Options for ${member_name}`); + wrapperDeleteAction.innerHTML = generateKebabHTML('remove-member', unique_id, cancelInvitationButton, `More Options for ${member_name}`, "usa-icon--large"); // This easter egg is only for fixtures that dont have names as we are displaying their emails // All prod users will have emails linked to their account @@ -100,8 +100,8 @@ export function initAddNewMemberPageListeners() { const permissionSections = document.querySelectorAll(`#${permission_details_div_id} > h3`); permissionSections.forEach(section => { - // Find the

element text - const sectionTitle = section.textContent; + // Find the

element text, strip out the '*' + const sectionTitle = section.textContent.trim().replace(/\*$/, "") + ": "; // Find the associated radio buttons container (next fieldset) const fieldset = section.nextElementSibling; @@ -128,25 +128,29 @@ export function initAddNewMemberPageListeners() { }); } else { // for admin users, the permissions are always the same - appendPermissionInContainer('Domains', 'Viewer', permissionDetailsContainer); - appendPermissionInContainer('Domain requests', 'Creator', permissionDetailsContainer); - appendPermissionInContainer('Members', 'Manager', permissionDetailsContainer); + appendPermissionInContainer('Domains: ', 'Viewer', permissionDetailsContainer); + appendPermissionInContainer('Domain requests: ', 'Creator', permissionDetailsContainer); + appendPermissionInContainer('Members: ', 'Manager', permissionDetailsContainer); } } function appendPermissionInContainer(sectionTitle, permissionDisplay, permissionContainer) { // Create new elements for the content - const titleElement = document.createElement("h4"); - titleElement.textContent = sectionTitle; - titleElement.classList.add("text-primary", "margin-bottom-0"); + const elementContainer = document.createElement("p"); + elementContainer.classList.add("margin-top-0", "margin-bottom-1"); - const permissionElement = document.createElement("p"); + const titleElement = document.createElement("strong"); + titleElement.textContent = sectionTitle; + titleElement.classList.add("text-primary-darker"); + + const permissionElement = document.createElement("span"); permissionElement.textContent = permissionDisplay; - permissionElement.classList.add("margin-top-0"); // Append to the content container - permissionContainer.appendChild(titleElement); - permissionContainer.appendChild(permissionElement); + elementContainer.appendChild(titleElement); + elementContainer.appendChild(permissionElement); + + permissionContainer.appendChild(elementContainer); } /* diff --git a/src/registrar/assets/src/js/getgov/table-base.js b/src/registrar/assets/src/js/getgov/table-base.js index ce4397887..bf561fa1f 100644 --- a/src/registrar/assets/src/js/getgov/table-base.js +++ b/src/registrar/assets/src/js/getgov/table-base.js @@ -79,13 +79,13 @@ export function addModal(id, ariaLabelledby, ariaDescribedby, modalHeading, moda * @param {string} modal_button_text - The action button's text * @param {string} screen_reader_text - A screen reader helper */ -export function generateKebabHTML(action, unique_id, modal_button_text, screen_reader_text) { +export function generateKebabHTML(action, unique_id, modal_button_text, screen_reader_text, icon_class) { const generateModalButton = (mobileOnly = false) => ` @@ -99,7 +99,7 @@ export function generateKebabHTML(action, unique_id, modal_button_text, screen_r // Main kebab structure const kebab = ` ${generateModalButton(true)} -
+
-
- Enable DNSSEC + Enable DNSSEC
{% endif %} diff --git a/src/registrar/templates/domain_dsdata.html b/src/registrar/templates/domain_dsdata.html index 36eb811e3..95e8e3d5f 100644 --- a/src/registrar/templates/domain_dsdata.html +++ b/src/registrar/templates/domain_dsdata.html @@ -18,13 +18,13 @@ Domains
  • - {{ domain.name }} + {{ domain.name }}
  • - DNS + DNS
  • - DNSSEC + DNSSEC
  • DS data diff --git a/src/registrar/templates/domain_nameservers.html b/src/registrar/templates/domain_nameservers.html index ad8d61592..1b1a59c9e 100644 --- a/src/registrar/templates/domain_nameservers.html +++ b/src/registrar/templates/domain_nameservers.html @@ -19,10 +19,10 @@ Domains
  • - {{ domain.name }} + {{ domain.name }}
  • - DNS + DNS
  • DNS name servers diff --git a/src/registrar/templates/domain_renewal.html b/src/registrar/templates/domain_renewal.html index 703c2358f..8af43c6eb 100644 --- a/src/registrar/templates/domain_renewal.html +++ b/src/registrar/templates/domain_renewal.html @@ -24,7 +24,7 @@ Domains
  • - {{domain.name}} + {{domain.name}}
  • Renewal Form @@ -63,14 +63,14 @@ {% endif %} {% endif %} - {% url 'domain-security-email' pk=domain.id as url %} + {% url 'domain-security-email' domain_pk=domain.id as url %} {% if security_email is not None and security_email not in hidden_security_emails%} {% include "includes/summary_item.html" with title='Security email' value=security_email custom_text_for_value_none='We strongly recommend that you provide a security email. This email will allow the public to report observed or suspected security issues on your domain.' edit_link=url editable=is_editable %} {% else %} {% include "includes/summary_item.html" with title='Security email' value='None provided' custom_text_for_value_none='We strongly recommend that you provide a security email. This email will allow the public to report observed or suspected security issues on your domain.' edit_link=url editable=is_editable %} {% endif %} - {% url 'domain-users' pk=domain.id as url %} + {% url 'domain-users' domain_pk=domain.id as url %} {% if portfolio %} {% include "includes/summary_item.html" with title='Domain managers' domain_permissions=True value=domain edit_link=url editable=is_editable %} {% else %} @@ -91,7 +91,7 @@ Acknowledgement of .gov domain requirements
  • -
    + {% csrf_token %}
    diff --git a/src/registrar/templates/domain_request_current_sites.html b/src/registrar/templates/domain_request_current_sites.html index 769906309..8eb5bb0d1 100644 --- a/src/registrar/templates/domain_request_current_sites.html +++ b/src/registrar/templates/domain_request_current_sites.html @@ -20,7 +20,7 @@ {% endwith %} {% endfor %} -
    diff --git a/src/registrar/templates/domain_security_email.html b/src/registrar/templates/domain_security_email.html index 38a5a43c5..e74ecf709 100644 --- a/src/registrar/templates/domain_security_email.html +++ b/src/registrar/templates/domain_security_email.html @@ -16,7 +16,7 @@ Domains
  • - {{ domain.name }} + {{ domain.name }}
  • Security email diff --git a/src/registrar/templates/domain_sidebar.html b/src/registrar/templates/domain_sidebar.html index 3302a6a79..ed384d5cd 100644 --- a/src/registrar/templates/domain_sidebar.html +++ b/src/registrar/templates/domain_sidebar.html @@ -17,14 +17,14 @@ {% endif %}
  • - {% url 'domain-dns' pk=domain.id as url %} + {% url 'domain-dns' domain_pk=domain.id as url %} DNS {% if request.path|startswith:url %}