From f7645228dd69272d0e3b419194d50f8edb60878b Mon Sep 17 00:00:00 2001 From: Jaxon Silva Date: Thu, 13 Feb 2025 10:46:47 -0800 Subject: [PATCH 01/15] Removed thank you text from ineligible states --- src/registrar/templates/emails/status_change_rejected.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/registrar/templates/emails/status_change_rejected.txt b/src/registrar/templates/emails/status_change_rejected.txt index e56d46a1f..2fc44c504 100644 --- a/src/registrar/templates/emails/status_change_rejected.txt +++ b/src/registrar/templates/emails/status_change_rejected.txt @@ -69,8 +69,10 @@ NEED ASSISTANCE? If you have questions about this domain request or need help choosing a new domain name, reply to this email. {% endif %} +{% if reason != domain_request.RejectionReasons.REQUESTOR_NOT_ELIGIBLE %} THANK YOU .Gov helps the public identify official, trusted information. Thank you for requesting a .gov domain. +{% endif %} ---------------------------------------------------------------- From 2c75a8dfbd509032c05ca47b40c846fec0db308e Mon Sep 17 00:00:00 2001 From: Jaxon Silva Date: Thu, 13 Feb 2025 11:06:01 -0800 Subject: [PATCH 02/15] Update status_change_rejected.txt --- src/registrar/templates/emails/status_change_rejected.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/templates/emails/status_change_rejected.txt b/src/registrar/templates/emails/status_change_rejected.txt index 2fc44c504..a222e6088 100644 --- a/src/registrar/templates/emails/status_change_rejected.txt +++ b/src/registrar/templates/emails/status_change_rejected.txt @@ -68,12 +68,12 @@ Learn more about: NEED ASSISTANCE? If you have questions about this domain request or need help choosing a new domain name, reply to this email. {% endif %} - {% if reason != domain_request.RejectionReasons.REQUESTOR_NOT_ELIGIBLE %} + THANK YOU .Gov helps the public identify official, trusted information. Thank you for requesting a .gov domain. -{% endif %} +{% endif %} ---------------------------------------------------------------- The .gov team From 3a12e59db65c2a76a4151603e6d2442dd8cb0f24 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 18 Feb 2025 15:02:53 -0700 Subject: [PATCH 03/15] Fix andi errors --- src/registrar/admin.py | 7 ++++--- src/registrar/assets/src/sass/_theme/_admin.scss | 4 ++++ .../templates/admin/change_list_results.html | 10 +++++----- src/registrar/templatetags/custom_filters.py | 14 +++++++++----- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 2d2b90a5f..9dae19a22 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -2287,11 +2287,12 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin): @admin.display(description=_("Requested Domain")) def custom_requested_domain(self, obj): # Example: Show different icons based on `status` - url = reverse("admin:registrar_domainrequest_changelist") + f"{obj.id}" text = obj.requested_domain if obj.portfolio: - return format_html(' {}', url, text) - return format_html('{}', url, text) + return format_html( + f' {escape(text)}' + ) + return text custom_requested_domain.admin_order_field = "requested_domain__name" # type: ignore diff --git a/src/registrar/assets/src/sass/_theme/_admin.scss b/src/registrar/assets/src/sass/_theme/_admin.scss index a15d1eabe..79fc6273e 100644 --- a/src/registrar/assets/src/sass/_theme/_admin.scss +++ b/src/registrar/assets/src/sass/_theme/_admin.scss @@ -982,3 +982,7 @@ ul.add-list-reset { } } + +#result_list > tbody tr > th > a { + text-decoration: underline; +} \ No newline at end of file diff --git a/src/registrar/templates/admin/change_list_results.html b/src/registrar/templates/admin/change_list_results.html index 5e4f37711..f55ac7197 100644 --- a/src/registrar/templates/admin/change_list_results.html +++ b/src/registrar/templates/admin/change_list_results.html @@ -19,11 +19,11 @@ Load our custom filters to extract info from the django generated markup. {% if results.0|contains_checkbox %} {# .gov - hardcode the select all checkbox #} - +
- +
@@ -61,10 +61,10 @@ Load our custom filters to extract info from the django generated markup. {% endif %} {% with result_value=result.0|extract_value %} - {% with result_label=result.1|extract_a_text %} + {% with result_label=result.1|extract_a_text checkbox_id="select-"|add:result_value %} - - + + {% endwith %} {% endwith %} diff --git a/src/registrar/templatetags/custom_filters.py b/src/registrar/templatetags/custom_filters.py index ff73e6dc1..cf2abf447 100644 --- a/src/registrar/templatetags/custom_filters.py +++ b/src/registrar/templatetags/custom_filters.py @@ -25,11 +25,15 @@ def extract_a_text(value): pattern = r"]*>(.*?)" match = re.search(pattern, value) if match: - extracted_text = match.group(1) - else: - extracted_text = "" - - return extracted_text + # Get the content and strip any nested HTML tags + content = match.group(1) + # Remove any nested HTML tags (like ) + text_pattern = r"<[^>]+>" + text_only = re.sub(text_pattern, "", content) + # Clean up any extra whitespace + return text_only.strip() + + return "" @register.filter From 0e09e5720bc49b9ecf677be53f7bbceaf412c52f Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 19 Feb 2025 10:45:47 -0700 Subject: [PATCH 04/15] Test making button clickable --- .../assets/src/js/getgov-admin/button-utils.js | 16 ++++++++++++++++ src/registrar/assets/src/js/getgov-admin/main.js | 2 ++ .../import_export/change_list_export_item.html | 7 +++++++ .../import_export/change_list_import_item.html | 2 +- 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/registrar/assets/src/js/getgov-admin/button-utils.js create mode 100644 src/registrar/templates/admin/import_export/change_list_export_item.html diff --git a/src/registrar/assets/src/js/getgov-admin/button-utils.js b/src/registrar/assets/src/js/getgov-admin/button-utils.js new file mode 100644 index 000000000..79d9091d6 --- /dev/null +++ b/src/registrar/assets/src/js/getgov-admin/button-utils.js @@ -0,0 +1,16 @@ +/** + * Initializes buttons to behave like links by navigating to their data-url attribute + * Example usage: + */ +export function initButtonLinks() { + document.querySelectorAll('button.use-button-as-link').forEach(button => { + button.addEventListener('click', function() { + // Equivalent to button.getAttribute("data-href") + const href = this.dataset.href; + console.log(`in loop: ${href}`) + if (href) { + window.location.href = href; + } + }); + }); +} diff --git a/src/registrar/assets/src/js/getgov-admin/main.js b/src/registrar/assets/src/js/getgov-admin/main.js index 5c6de20ab..7eb1fc8cd 100644 --- a/src/registrar/assets/src/js/getgov-admin/main.js +++ b/src/registrar/assets/src/js/getgov-admin/main.js @@ -16,6 +16,7 @@ import { initDynamicPortfolioFields } from './portfolio-form.js'; import { initDynamicDomainInformationFields } from './domain-information-form.js'; import { initDynamicDomainFields } from './domain-form.js'; import { initAnalyticsDashboard } from './analytics.js'; +import { initButtonLinks } from './button-utils.js'; // General initModals(); @@ -23,6 +24,7 @@ initCopyToClipboard(); initFilterHorizontalWidget(); initDescriptions(); initSubmitBar(); +initButtonLinks(); // Domain request initIneligibleModal(); diff --git a/src/registrar/templates/admin/import_export/change_list_export_item.html b/src/registrar/templates/admin/import_export/change_list_export_item.html new file mode 100644 index 000000000..9678d224a --- /dev/null +++ b/src/registrar/templates/admin/import_export/change_list_export_item.html @@ -0,0 +1,7 @@ +{% load i18n %} +{% load admin_urls %} + +{% if has_export_permission %} +{% comment %} Uses the initButtonLinks {% endcomment %} +
  • +{% endif %} diff --git a/src/registrar/templates/admin/import_export/change_list_import_item.html b/src/registrar/templates/admin/import_export/change_list_import_item.html index 8255a8ba7..0f2d59421 100644 --- a/src/registrar/templates/admin/import_export/change_list_import_item.html +++ b/src/registrar/templates/admin/import_export/change_list_import_item.html @@ -3,6 +3,6 @@ {% if has_import_permission %} {% if not IS_PRODUCTION %} -
  • {% trans "Import" %}
  • +
  • {% endif %} {% endif %} From 4a634936e65d6bc8df5208f3b2e2abdadd270c67 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 19 Feb 2025 12:10:16 -0700 Subject: [PATCH 05/15] Change all buttons to
  • - {% translate "View on site" %} +
  • {% else %} @@ -30,18 +30,18 @@ {% endif %}
  • - {% translate "History" %} +
  • {% if opts.model_name == 'domainrequest' %}
  • - +
  • {% endif %} diff --git a/src/registrar/templates/admin/change_list_object_tools.html b/src/registrar/templates/admin/change_list_object_tools.html index 9a046b4bb..5ba88aa3a 100644 --- a/src/registrar/templates/admin/change_list_object_tools.html +++ b/src/registrar/templates/admin/change_list_object_tools.html @@ -5,9 +5,9 @@ {% if has_add_permission %}

    {% url cl.opts|admin_urlname:'add' as add_url %} - +

    {% endif %} {% endblock %} \ No newline at end of file From 20ff3541b43706d609d4349efd444a83f84dbee7 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 19 Feb 2025 13:09:59 -0700 Subject: [PATCH 06/15] fix aria warning --- .../templates/admin/search_form.html | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/registrar/templates/admin/search_form.html diff --git a/src/registrar/templates/admin/search_form.html b/src/registrar/templates/admin/search_form.html new file mode 100644 index 000000000..c5fcf31f8 --- /dev/null +++ b/src/registrar/templates/admin/search_form.html @@ -0,0 +1,26 @@ +{% comment %} This is an override of the django search bar to add better accessibility compliance. +There are no blocks defined here, so we had to copy the code. +https://github.com/django/django/blob/main/django/contrib/admin/templates/admin/search_form.html +{% endcomment %} +{% load i18n static %} +{% if cl.search_fields %} +
    +{% endif %} \ No newline at end of file From 2cfce34edebaefaefa199549de245e9358dbe5d1 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 19 Feb 2025 13:24:15 -0700 Subject: [PATCH 07/15] Add aria-label for table sort buttons --- src/registrar/templates/admin/change_list_results.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/templates/admin/change_list_results.html b/src/registrar/templates/admin/change_list_results.html index f55ac7197..c5be04133 100644 --- a/src/registrar/templates/admin/change_list_results.html +++ b/src/registrar/templates/admin/change_list_results.html @@ -34,9 +34,9 @@ Load our custom filters to extract info from the django generated markup. {% if header.sortable %} {% if header.sort_priority > 0 %}
    - + {% if num_sorted_fields > 1 %}{{ header.sort_priority }}{% endif %} - +
    {% endif %} {% endif %} From 3bfb75fa3bd5a5309f36fd08636ca47dd3d4efa9 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 19 Feb 2025 13:27:35 -0700 Subject: [PATCH 08/15] Update src/registrar/assets/src/sass/_theme/_admin.scss --- src/registrar/assets/src/sass/_theme/_admin.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/assets/src/sass/_theme/_admin.scss b/src/registrar/assets/src/sass/_theme/_admin.scss index f136fb098..bd55bbfcb 100644 --- a/src/registrar/assets/src/sass/_theme/_admin.scss +++ b/src/registrar/assets/src/sass/_theme/_admin.scss @@ -995,4 +995,4 @@ ul.add-list-reset { #result_list > tbody tr > th > a { text-decoration: underline; -} \ No newline at end of file +} From 234a846d5a3f4980c57b364407250181c1dd4e33 Mon Sep 17 00:00:00 2001 From: Jaxon Silva Date: Wed, 19 Feb 2025 16:31:26 -0800 Subject: [PATCH 09/15] Update status_change_rejected.txt Added additional state for "organization not eligible" --- src/registrar/templates/emails/status_change_rejected.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/templates/emails/status_change_rejected.txt b/src/registrar/templates/emails/status_change_rejected.txt index a222e6088..e865031fa 100644 --- a/src/registrar/templates/emails/status_change_rejected.txt +++ b/src/registrar/templates/emails/status_change_rejected.txt @@ -68,7 +68,7 @@ Learn more about: NEED ASSISTANCE? If you have questions about this domain request or need help choosing a new domain name, reply to this email. {% endif %} -{% if reason != domain_request.RejectionReasons.REQUESTOR_NOT_ELIGIBLE %} +{% if reason != domain_request.RejectionReasons.REQUESTOR_NOT_ELIGIBLE and reason != domain_request.RejectionReasons.ORG_NOT_ELIGIBLE %} THANK YOU .Gov helps the public identify official, trusted information. Thank you for requesting a .gov domain. From eb02869df82bf363c70aadc63dcb564376fd5ddd Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 20 Feb 2025 08:57:09 -0700 Subject: [PATCH 10/15] lint --- src/registrar/assets/src/js/getgov-admin/button-utils.js | 1 - src/registrar/templatetags/custom_filters.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/registrar/assets/src/js/getgov-admin/button-utils.js b/src/registrar/assets/src/js/getgov-admin/button-utils.js index 79d9091d6..e3746d289 100644 --- a/src/registrar/assets/src/js/getgov-admin/button-utils.js +++ b/src/registrar/assets/src/js/getgov-admin/button-utils.js @@ -7,7 +7,6 @@ export function initButtonLinks() { button.addEventListener('click', function() { // Equivalent to button.getAttribute("data-href") const href = this.dataset.href; - console.log(`in loop: ${href}`) if (href) { window.location.href = href; } diff --git a/src/registrar/templatetags/custom_filters.py b/src/registrar/templatetags/custom_filters.py index cf2abf447..e02a29e73 100644 --- a/src/registrar/templatetags/custom_filters.py +++ b/src/registrar/templatetags/custom_filters.py @@ -32,7 +32,7 @@ def extract_a_text(value): text_only = re.sub(text_pattern, "", content) # Clean up any extra whitespace return text_only.strip() - + return "" From 699db826d08d6bff191d8927c8c0213b6f869c8c Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Mon, 24 Feb 2025 10:59:26 -0700 Subject: [PATCH 11/15] Move button to other row to fix tab issue --- .../assets/src/js/getgov/table-members.js | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/registrar/assets/src/js/getgov/table-members.js b/src/registrar/assets/src/js/getgov/table-members.js index 29d140185..26a11da09 100644 --- a/src/registrar/assets/src/js/getgov/table-members.js +++ b/src/registrar/assets/src/js/getgov/table-members.js @@ -69,6 +69,7 @@ export class MembersTable extends BaseTable { const kebabHTML = customTableOptions.hasAdditionalActions ? generateKebabHTML('remove-member', unique_id, cancelInvitationButton, `Expand for more options for ${member.name}`): ''; const row = document.createElement('tr'); + row.classList.add('hide-td-borders'); let admin_tagHTML = ``; if (member.is_admin) admin_tagHTML = `Admin` @@ -96,20 +97,26 @@ export class MembersTable extends BaseTable { `; - showMoreRow.innerHTML = `
    ${domainsHTML} ${permissionsHTML}
    `; - showMoreRow.classList.add('show-more-content'); - showMoreRow.classList.add('display-none'); + showMoreRow.innerHTML = ` + + ${showMoreButton} + + + `; showMoreRow.id = unique_id; } row.innerHTML = ` - - ${member.member_display} ${admin_tagHTML} ${showMoreButton} + + ${member.member_display} ${admin_tagHTML} - + ${last_active.display_value} - +
    Admin` // generate html blocks for domains and permissions for the member - let domainsHTML = this.generateDomainsHTML(num_domains, member.domain_names, member.domain_urls, member.action_url); - let permissionsHTML = this.generatePermissionsHTML(member.is_admin, member.permissions, customTableOptions.UserPortfolioPermissionChoices); + let domainsHTML = this.generateDomainsHTML(num_domains, member.domain_names, member.domain_urls, member.action_url, unique_id); + let permissionsHTML = this.generatePermissionsHTML(member.is_admin, member.permissions, customTableOptions.UserPortfolioPermissionChoices, unique_id); // domainsHTML block and permissionsHTML block need to be wrapped with hide/show toggle, Expand let showMoreButton = ''; @@ -243,16 +243,18 @@ export class MembersTable extends BaseTable { * @param {number} num_domains - The number of domains the member is assigned to. * @param {Array} domain_names - An array of domain names. * @param {Array} domain_urls - An array of corresponding domain URLs. + * @param {Array} unique_id - A unique row id. * @returns {string} - A string of HTML displaying the domains assigned to the member. */ - generateDomainsHTML(num_domains, domain_names, domain_urls, action_url) { + generateDomainsHTML(num_domains, domain_names, domain_urls, action_url, unique_id) { // Initialize an empty string for the HTML let domainsHTML = ''; // Only generate HTML if the member has one or more assigned domains domainsHTML += ""; return domainsHTML; @@ -368,7 +370,7 @@ export class MembersTable extends BaseTable { * - VIEW_ALL_REQUESTS * - EDIT_MEMBERS * - VIEW_MEMBERS - * + * @param {String} unique_id * @returns {string} - A string of HTML representing the user's additional permissions. * If the user has no specific permissions, it returns a default message * indicating no additional permissions. @@ -383,51 +385,51 @@ export class MembersTable extends BaseTable { * - If no relevant permissions are found, the function returns a message stating that the user has no additional permissions. * - The resulting HTML always includes a header "Additional permissions for this member" and appends the relevant permission descriptions. */ - generatePermissionsHTML(is_admin, member_permissions, UserPortfolioPermissionChoices) { - let permissionsHTML = ''; - - // Define shared classes across elements for easier refactoring - let sharedParagraphClasses = "font-body-xs text-base-darker margin-top-1 p--blockquote"; - - // Member access - if (is_admin) { - permissionsHTML += `

    Member access: Admin

    `; - } else { - permissionsHTML += `

    Member access: Basic

    `; - } - - // Check domain-related permissions + generatePermissionsHTML(is_admin, member_permissions, UserPortfolioPermissionChoices, unique_id) { + // 1. Role + const memberAccessValue = is_admin ? "Admin" : "Basic"; + + // 2. Domain access + let domainValue = "No access"; if (member_permissions.includes(UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS)) { - permissionsHTML += `

    Domains: Viewer

    `; + domainValue = "Viewer"; } else if (member_permissions.includes(UserPortfolioPermissionChoices.VIEW_MANAGED_DOMAINS)) { - permissionsHTML += `

    Domains: Viewer, limited

    `; + domainValue = "Viewer, limited"; } - - // Check request-related permissions + + // 3. Request access + let requestValue = "No access"; if (member_permissions.includes(UserPortfolioPermissionChoices.EDIT_REQUESTS)) { - permissionsHTML += `

    Domain requests: Creator

    `; + requestValue = "Creator"; } else if (member_permissions.includes(UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS)) { - permissionsHTML += `

    Domain requests: Viewer

    `; - } else { - permissionsHTML += `

    Domain requests: No access

    `; + requestValue = "Viewer"; } - - // Check member-related permissions + + // 4. Member access + let memberValue = "No access"; if (member_permissions.includes(UserPortfolioPermissionChoices.EDIT_MEMBERS)) { - permissionsHTML += `

    Members: Manager

    `; + memberValue = "Manager"; } else if (member_permissions.includes(UserPortfolioPermissionChoices.VIEW_MEMBERS)) { - permissionsHTML += `

    Members: Viewer

    `; - } else { - permissionsHTML += `

    Members: No access

    `; + memberValue = "Viewer"; } - - // If no specific permissions are assigned, display a message indicating no additional permissions - if (!permissionsHTML) { - permissionsHTML += `

    No additional permissions: There are no additional permissions for this member.

    `; - } - - // Add a permissions header and wrap the entire output in a container - permissionsHTML = `

    Member access and permissions

    ${permissionsHTML}
    `; + + // Helper function for faster element refactoring + const createPermissionItem = (label, value) => { + return `

    ${label}: ${value}

    `; + }; + const permissionsHTML = ` +
    +

    + Member access and permissions +

    +
    + ${createPermissionItem("Member access", memberAccessValue)} + ${createPermissionItem("Domains", domainValue)} + ${createPermissionItem("Domain requests", requestValue)} + ${createPermissionItem("Members", memberValue)} +
    +
    + `; return permissionsHTML; } From 6f96e70002d5fa051b54a54869560cf118fd0df4 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 25 Feb 2025 09:26:57 -0700 Subject: [PATCH 14/15] Update table-members.js --- src/registrar/assets/src/js/getgov/table-members.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/assets/src/js/getgov/table-members.js b/src/registrar/assets/src/js/getgov/table-members.js index 28a73f013..44589ffa7 100644 --- a/src/registrar/assets/src/js/getgov/table-members.js +++ b/src/registrar/assets/src/js/getgov/table-members.js @@ -254,7 +254,7 @@ export class MembersTable extends BaseTable { domainsHTML += "
    "; domainsHTML += `

    Domains assigned

    `; - domainsHTML += `
    ` + domainsHTML += `
    ` if (num_domains > 0) { domainsHTML += `

    This member is assigned to ${num_domains} domain${num_domains > 1 ? 's' : ''}:

    `; domainsHTML += "
      "; From d5c1ce0de07b1fefd6ba4b17b9e2b66bc344f800 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 25 Feb 2025 09:31:33 -0700 Subject: [PATCH 15/15] Fix screenreader issue --- .../assets/src/js/getgov/table-members.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/registrar/assets/src/js/getgov/table-members.js b/src/registrar/assets/src/js/getgov/table-members.js index 44589ffa7..a13894e95 100644 --- a/src/registrar/assets/src/js/getgov/table-members.js +++ b/src/registrar/assets/src/js/getgov/table-members.js @@ -257,14 +257,19 @@ export class MembersTable extends BaseTable { domainsHTML += `
      ` if (num_domains > 0) { domainsHTML += `

      This member is assigned to ${num_domains} domain${num_domains > 1 ? 's' : ''}:

      `; - domainsHTML += "
        "; + if (num_domains > 1) { + domainsHTML += "
          "; - // Display up to 6 domains with their URLs - for (let i = 0; i < num_domains && i < 6; i++) { - domainsHTML += `
        • ${domain_names[i]}
        • `; + // Display up to 6 domains with their URLs + for (let i = 0; i < num_domains && i < 6; i++) { + domainsHTML += `
        • ${domain_names[i]}
        • `; + } + + domainsHTML += "
        "; + } else { + // We don't display this in a list for better screenreader support, when only one item exists. + domainsHTML += `${domain_names[0]}`; } - - domainsHTML += "
      "; } else { domainsHTML += `

      This member is assigned to 0 domains.

      `; }