diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js
index 02e6ea242..47217c495 100644
--- a/src/registrar/assets/js/get-gov.js
+++ b/src/registrar/assets/js/get-gov.js
@@ -912,180 +912,183 @@ function ScrollToElement(attributeName, attributeValue) {
*
*/
document.addEventListener('DOMContentLoaded', function() {
- let currentSortBy = 'id';
- let currentOrder = 'asc';
let domainsWrapper = document.querySelector('.domains-wrapper');
- let noDomainsWrapper = document.querySelector('.no-domains-wrapper');
- let hasLoaded = false;
- /**
- * Loads rows in the domains list, as well as updates pagination around the domains list
- * based on the supplied attributes.
- * @param {*} page - the page number of the results (starts with 1)
- * @param {*} sortBy - the sort column option
- * @param {*} order - the sort order {asc, desc}
- * @param {*} loaded - control for the scrollToElement functionality
- */
- function loadDomains(page, sortBy = currentSortBy, order = currentOrder, loaded = hasLoaded) {
- //fetch json of page of domains, given page # and sort
- fetch(`/get-domains-json/?page=${page}&sort_by=${sortBy}&order=${order}`)
- .then(response => response.json())
- .then(data => {
- if (data.error) {
- console.log('Error in AJAX call: ' + data.error);
- return;
- }
+ if (domainsWrapper) {
+ let currentSortBy = 'id';
+ let currentOrder = 'asc';
+ let noDomainsWrapper = document.querySelector('.no-domains-wrapper');
+ let hasLoaded = false;
- // handle the display of proper messaging in the event that no domains exist in the list
- if (data.domains.length) {
- domainsWrapper.classList.remove('display-none');
- noDomainsWrapper.classList.add('display-none');
- } else {
- domainsWrapper.classList.add('display-none');
- noDomainsWrapper.classList.remove('display-none');
- }
+ /**
+ * Loads rows in the domains list, as well as updates pagination around the domains list
+ * based on the supplied attributes.
+ * @param {*} page - the page number of the results (starts with 1)
+ * @param {*} sortBy - the sort column option
+ * @param {*} order - the sort order {asc, desc}
+ * @param {*} loaded - control for the scrollToElement functionality
+ */
+ function loadDomains(page, sortBy = currentSortBy, order = currentOrder, loaded = hasLoaded) {
+ //fetch json of page of domains, given page # and sort
+ fetch(`/get-domains-json/?page=${page}&sort_by=${sortBy}&order=${order}`)
+ .then(response => response.json())
+ .then(data => {
+ if (data.error) {
+ console.log('Error in AJAX call: ' + data.error);
+ return;
+ }
- // identify the DOM element where the domain list will be inserted into the DOM
- const domainList = document.querySelector('.dotgov-table__registered-domains tbody');
- domainList.innerHTML = '';
+ // handle the display of proper messaging in the event that no domains exist in the list
+ if (data.domains.length) {
+ domainsWrapper.classList.remove('display-none');
+ noDomainsWrapper.classList.add('display-none');
+ } else {
+ domainsWrapper.classList.add('display-none');
+ noDomainsWrapper.classList.remove('display-none');
+ }
- data.domains.forEach(domain => {
- const expirationDate = domain.expiration_date ? new Date(domain.expiration_date) : null;
- const expirationDateSortValue = expirationDate ? expirationDate.getTime() : '';
- const actionUrl = domain.action_url;
-
- const row = document.createElement('tr');
- row.innerHTML = `
-
+ `;
+ domainList.appendChild(row);
+ });
+ // initialize tool tips immediately after the associated DOM elements are added
+ initializeTooltips();
+ if (loaded)
+ ScrollToElement('id', 'domains-header');
- hasLoaded = true;
+ hasLoaded = true;
- // update pagination
- updateDomainsPagination(data.page, data.num_pages, data.has_previous, data.has_next, data.total);
- currentSortBy = sortBy;
- currentOrder = order;
- })
- .catch(error => console.error('Error fetching domains:', error));
- }
-
- /**
- * Update the pagination below the domains list.
- * @param {*} currentPage - the current page number (starting with 1)
- * @param {*} numPages - the number of pages indicated by the domains list response
- * @param {*} hasPrevious - if there is a page of results prior to the current page
- * @param {*} hasNext - if there is a page of results after the current page
- */
- function updateDomainsPagination(currentPage, numPages, hasPrevious, hasNext, totalItems) {
- // identify the DOM element where the pagination will be inserted
- const paginationContainer = document.querySelector('#domains-pagination');
- const paginationCounter = document.querySelector('#domains-pagination .usa-pagination__counter');
- const paginationButtons = document.querySelector('#domains-pagination .usa-pagination__list');
- paginationCounter.innerHTML = '';
- paginationButtons.innerHTML = '';
-
- // Buttons should only be displayed if there are more than one pages of results
- paginationButtons.classList.toggle('display-none', numPages <= 1);
-
- // Counter should only be displayed if there is more than 1 item
- paginationContainer.classList.toggle('display-none', totalItems < 1);
-
- paginationCounter.innerHTML = `${totalItems} domain${totalItems > 1 ? 's' : ''}`;
-
- if (hasPrevious) {
- const prevPageItem = document.createElement('li');
- prevPageItem.className = 'usa-pagination__item usa-pagination__arrow';
- prevPageItem.innerHTML = `
-
-
-
-
- Previous
-
- `;
- prevPageItem.querySelector('a').addEventListener('click', () => loadDomains(currentPage - 1));
- paginationButtons.appendChild(prevPageItem);
+ // update pagination
+ updateDomainsPagination(data.page, data.num_pages, data.has_previous, data.has_next, data.total);
+ currentSortBy = sortBy;
+ currentOrder = order;
+ })
+ .catch(error => console.error('Error fetching domains:', error));
}
- for (let i = 1; i <= numPages; i++) {
- const pageItem = document.createElement('li');
- pageItem.className = 'usa-pagination__item usa-pagination__page-no';
- pageItem.innerHTML = `
- ${i}
- `;
- if (i === currentPage) {
- pageItem.querySelector('a').classList.add('usa-current');
- pageItem.querySelector('a').setAttribute('aria-current', 'page');
+ /**
+ * Update the pagination below the domains list.
+ * @param {*} currentPage - the current page number (starting with 1)
+ * @param {*} numPages - the number of pages indicated by the domains list response
+ * @param {*} hasPrevious - if there is a page of results prior to the current page
+ * @param {*} hasNext - if there is a page of results after the current page
+ */
+ function updateDomainsPagination(currentPage, numPages, hasPrevious, hasNext, totalItems) {
+ // identify the DOM element where the pagination will be inserted
+ const paginationContainer = document.querySelector('#domains-pagination');
+ const paginationCounter = document.querySelector('#domains-pagination .usa-pagination__counter');
+ const paginationButtons = document.querySelector('#domains-pagination .usa-pagination__list');
+ paginationCounter.innerHTML = '';
+ paginationButtons.innerHTML = '';
+
+ // Buttons should only be displayed if there are more than one pages of results
+ paginationButtons.classList.toggle('display-none', numPages <= 1);
+
+ // Counter should only be displayed if there is more than 1 item
+ paginationContainer.classList.toggle('display-none', totalItems < 1);
+
+ paginationCounter.innerHTML = `${totalItems} domain${totalItems > 1 ? 's' : ''}`;
+
+ if (hasPrevious) {
+ const prevPageItem = document.createElement('li');
+ prevPageItem.className = 'usa-pagination__item usa-pagination__arrow';
+ prevPageItem.innerHTML = `
+
+
+
+
+ Previous
+
+ `;
+ prevPageItem.querySelector('a').addEventListener('click', () => loadDomains(currentPage - 1));
+ paginationButtons.appendChild(prevPageItem);
}
- pageItem.querySelector('a').addEventListener('click', () => loadDomains(i));
- paginationButtons.appendChild(pageItem);
- }
- if (hasNext) {
- const nextPageItem = document.createElement('li');
- nextPageItem.className = 'usa-pagination__item usa-pagination__arrow';
- nextPageItem.innerHTML = `
-
- Next
-
-
-
-
- `;
- nextPageItem.querySelector('a').addEventListener('click', () => loadDomains(currentPage + 1));
- paginationButtons.appendChild(nextPageItem);
- }
- }
-
- // Add event listeners to table headers for sorting
- document.querySelectorAll('.dotgov-table__registered-domains th[data-sortable]').forEach(header => {
- header.addEventListener('click', function() {
- const sortBy = this.getAttribute('data-sortable');
- let order = 'asc';
- // sort order will be ascending, unless the currently sorted column is ascending, and the user
- // is selecting the same column to sort in descending order
- if (sortBy === currentSortBy) {
- order = currentOrder === 'asc' ? 'desc' : 'asc';
+ for (let i = 1; i <= numPages; i++) {
+ const pageItem = document.createElement('li');
+ pageItem.className = 'usa-pagination__item usa-pagination__page-no';
+ pageItem.innerHTML = `
+ ${i}
+ `;
+ if (i === currentPage) {
+ pageItem.querySelector('a').classList.add('usa-current');
+ pageItem.querySelector('a').setAttribute('aria-current', 'page');
+ }
+ pageItem.querySelector('a').addEventListener('click', () => loadDomains(i));
+ paginationButtons.appendChild(pageItem);
}
- // load the results with the updated sort
- loadDomains(1, sortBy, order);
+
+ if (hasNext) {
+ const nextPageItem = document.createElement('li');
+ nextPageItem.className = 'usa-pagination__item usa-pagination__arrow';
+ nextPageItem.innerHTML = `
+
+ Next
+
+
+
+
+ `;
+ nextPageItem.querySelector('a').addEventListener('click', () => loadDomains(currentPage + 1));
+ paginationButtons.appendChild(nextPageItem);
+ }
+ }
+
+ // Add event listeners to table headers for sorting
+ document.querySelectorAll('.dotgov-table__registered-domains th[data-sortable]').forEach(header => {
+ header.addEventListener('click', function() {
+ const sortBy = this.getAttribute('data-sortable');
+ let order = 'asc';
+ // sort order will be ascending, unless the currently sorted column is ascending, and the user
+ // is selecting the same column to sort in descending order
+ if (sortBy === currentSortBy) {
+ order = currentOrder === 'asc' ? 'desc' : 'asc';
+ }
+ // load the results with the updated sort
+ loadDomains(1, sortBy, order);
+ });
});
- });
- // Load the first page initially
- loadDomains(1);
+ // Load the first page initially
+ loadDomains(1);
+ }
});
/**
@@ -1094,185 +1097,188 @@ document.addEventListener('DOMContentLoaded', function() {
*
*/
document.addEventListener('DOMContentLoaded', function() {
- let currentSortBy = 'id';
- let currentOrder = 'asc';
let domainRequestsWrapper = document.querySelector('.domain-requests-wrapper');
- let noDomainRequestsWrapper = document.querySelector('.no-domain-requests-wrapper');
- let hasLoaded = false;
- /**
- * Loads rows in the domain requests list, as well as updates pagination around the domain requests list
- * based on the supplied attributes.
- * @param {*} page - the page number of the results (starts with 1)
- * @param {*} sortBy - the sort column option
- * @param {*} order - the sort order {asc, desc}
- * @param {*} loaded - control for the scrollToElement functionality
- */
- function loadDomainRequests(page, sortBy = currentSortBy, order = currentOrder, loaded = hasLoaded) {
- //fetch json of page of domain requests, given page # and sort
- fetch(`/get-domain-requests-json/?page=${page}&sort_by=${sortBy}&order=${order}`)
- .then(response => response.json())
- .then(data => {
- if (data.error) {
- console.log('Error in AJAX call: ' + data.error);
- return;
- }
+ if (domainRequestsWrapper) {
+ let currentSortBy = 'id';
+ let currentOrder = 'asc';
+ let noDomainRequestsWrapper = document.querySelector('.no-domain-requests-wrapper');
+ let hasLoaded = false;
- // handle the display of proper messaging in the event that no domain requests exist in the list
- if (data.domain_requests.length) {
- domainRequestsWrapper.classList.remove('display-none');
- noDomainRequestsWrapper.classList.add('display-none');
- } else {
- domainRequestsWrapper.classList.add('display-none');
- noDomainRequestsWrapper.classList.remove('display-none');
- }
+ /**
+ * Loads rows in the domain requests list, as well as updates pagination around the domain requests list
+ * based on the supplied attributes.
+ * @param {*} page - the page number of the results (starts with 1)
+ * @param {*} sortBy - the sort column option
+ * @param {*} order - the sort order {asc, desc}
+ * @param {*} loaded - control for the scrollToElement functionality
+ */
+ function loadDomainRequests(page, sortBy = currentSortBy, order = currentOrder, loaded = hasLoaded) {
+ //fetch json of page of domain requests, given page # and sort
+ fetch(`/get-domain-requests-json/?page=${page}&sort_by=${sortBy}&order=${order}`)
+ .then(response => response.json())
+ .then(data => {
+ if (data.error) {
+ console.log('Error in AJAX call: ' + data.error);
+ return;
+ }
- // identify the DOM element where the domain request list will be inserted into the DOM
- const tbody = document.querySelector('.dotgov-table__domain-requests tbody');
- tbody.innerHTML = '';
+ // handle the display of proper messaging in the event that no domain requests exist in the list
+ if (data.domain_requests.length) {
+ domainRequestsWrapper.classList.remove('display-none');
+ noDomainRequestsWrapper.classList.add('display-none');
+ } else {
+ domainRequestsWrapper.classList.add('display-none');
+ noDomainRequestsWrapper.classList.remove('display-none');
+ }
- // remove any existing modal elements from the DOM so they can be properly re-initialized
- // after the DOM content changes and there are new delete modal buttons added
- unloadModals();
- data.domain_requests.forEach(request => {
- const domainName = request.requested_domain ? request.requested_domain : `New domain request (${new Date(request.created_at).toLocaleString()} UTC)`;
- const submissionDate = request.submission_date ? new Date(request.submission_date).toLocaleDateString() : `Not submitted`;
- const actionUrl = request.action_url;
- const actionLabel = request.action_label;
- const deleteButton = request.is_deletable ? `
-
-
-
- Delete ${domainName}
- ` : '';
+ // identify the DOM element where the domain request list will be inserted into the DOM
+ const tbody = document.querySelector('.dotgov-table__domain-requests tbody');
+ tbody.innerHTML = '';
- const row = document.createElement('tr');
- row.innerHTML = `
-
+ `;
+ tbody.appendChild(row);
+ });
+ // initialize modals immediately after the DOM content is updated
+ initializeModals();
+ if (loaded)
+ ScrollToElement('id', 'domain-requests-header');
- // update the pagination after the domain requests list is updated
- updateDomainRequestsPagination(data.page, data.num_pages, data.has_previous, data.has_next, data.total);
- currentSortBy = sortBy;
- currentOrder = order;
- })
- .catch(error => console.error('Error fetching domain requests:', error));
- }
+ hasLoaded = true;
- /**
- * Update the pagination below the domain requests list.
- * @param {*} currentPage - the current page number (starting with 1)
- * @param {*} numPages - the number of pages indicated by the domain request list response
- * @param {*} hasPrevious - if there is a page of results prior to the current page
- * @param {*} hasNext - if there is a page of results after the current page
- */
- function updateDomainRequestsPagination(currentPage, numPages, hasPrevious, hasNext, totalItems) {
- // identify the DOM element where pagination is contained
- const paginationContainer = document.querySelector('#domain-requests-pagination');
- const paginationCounter = document.querySelector('#domain-requests-pagination .usa-pagination__counter');
- const paginationButtons = document.querySelector('#domain-requests-pagination .usa-pagination__list');
- paginationCounter.innerHTML = '';
- paginationButtons.innerHTML = '';
-
- // Buttons should only be displayed if there are more than one pages of results
- paginationButtons.classList.toggle('display-none', numPages <= 1);
-
- // Counter should only be displayed if there is more than 1 item
- paginationContainer.classList.toggle('display-none', totalItems < 1);
-
- paginationCounter.innerHTML = `${totalItems} domain request${totalItems > 1 ? 's' : ''}`;
-
- if (hasPrevious) {
- const prevPageItem = document.createElement('li');
- prevPageItem.className = 'usa-pagination__item usa-pagination__arrow';
- prevPageItem.innerHTML = `
-
-
-
-
- Previous
-
- `;
- prevPageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(currentPage - 1));
- paginationButtons.appendChild(prevPageItem);
+ // update the pagination after the domain requests list is updated
+ updateDomainRequestsPagination(data.page, data.num_pages, data.has_previous, data.has_next, data.total);
+ currentSortBy = sortBy;
+ currentOrder = order;
+ })
+ .catch(error => console.error('Error fetching domain requests:', error));
}
- for (let i = 1; i <= numPages; i++) {
- const pageItem = document.createElement('li');
- pageItem.className = 'usa-pagination__item usa-pagination__page-no';
- pageItem.innerHTML = `
- ${i}
- `;
- if (i === currentPage) {
- pageItem.querySelector('a').classList.add('usa-current');
- pageItem.querySelector('a').setAttribute('aria-current', 'page');
+ /**
+ * Update the pagination below the domain requests list.
+ * @param {*} currentPage - the current page number (starting with 1)
+ * @param {*} numPages - the number of pages indicated by the domain request list response
+ * @param {*} hasPrevious - if there is a page of results prior to the current page
+ * @param {*} hasNext - if there is a page of results after the current page
+ */
+ function updateDomainRequestsPagination(currentPage, numPages, hasPrevious, hasNext, totalItems) {
+ // identify the DOM element where pagination is contained
+ const paginationContainer = document.querySelector('#domain-requests-pagination');
+ const paginationCounter = document.querySelector('#domain-requests-pagination .usa-pagination__counter');
+ const paginationButtons = document.querySelector('#domain-requests-pagination .usa-pagination__list');
+ paginationCounter.innerHTML = '';
+ paginationButtons.innerHTML = '';
+
+ // Buttons should only be displayed if there are more than one pages of results
+ paginationButtons.classList.toggle('display-none', numPages <= 1);
+
+ // Counter should only be displayed if there is more than 1 item
+ paginationContainer.classList.toggle('display-none', totalItems < 1);
+
+ paginationCounter.innerHTML = `${totalItems} domain request${totalItems > 1 ? 's' : ''}`;
+
+ if (hasPrevious) {
+ const prevPageItem = document.createElement('li');
+ prevPageItem.className = 'usa-pagination__item usa-pagination__arrow';
+ prevPageItem.innerHTML = `
+
+
+
+
+ Previous
+
+ `;
+ prevPageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(currentPage - 1));
+ paginationButtons.appendChild(prevPageItem);
}
- pageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(i));
- paginationButtons.appendChild(pageItem);
- }
- if (hasNext) {
- const nextPageItem = document.createElement('li');
- nextPageItem.className = 'usa-pagination__item usa-pagination__arrow';
- nextPageItem.innerHTML = `
-
- Next
-
-
-
-
- `;
- nextPageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(currentPage + 1));
- paginationButtons.appendChild(nextPageItem);
- }
- }
-
- // Add event listeners to table headers for sorting
- document.querySelectorAll('.dotgov-table__domain-requests th[data-sortable]').forEach(header => {
- header.addEventListener('click', function() {
- const sortBy = this.getAttribute('data-sortable');
- let order = 'asc';
- // sort order will be ascending, unless the currently sorted column is ascending, and the user
- // is selecting the same column to sort in descending order
- if (sortBy === currentSortBy) {
- order = currentOrder === 'asc' ? 'desc' : 'asc';
+ for (let i = 1; i <= numPages; i++) {
+ const pageItem = document.createElement('li');
+ pageItem.className = 'usa-pagination__item usa-pagination__page-no';
+ pageItem.innerHTML = `
+ ${i}
+ `;
+ if (i === currentPage) {
+ pageItem.querySelector('a').classList.add('usa-current');
+ pageItem.querySelector('a').setAttribute('aria-current', 'page');
+ }
+ pageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(i));
+ paginationButtons.appendChild(pageItem);
}
- loadDomainRequests(1, sortBy, order);
+
+ if (hasNext) {
+ const nextPageItem = document.createElement('li');
+ nextPageItem.className = 'usa-pagination__item usa-pagination__arrow';
+ nextPageItem.innerHTML = `
+
+ Next
+
+
+
+
+ `;
+ nextPageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(currentPage + 1));
+ paginationButtons.appendChild(nextPageItem);
+ }
+ }
+
+ // Add event listeners to table headers for sorting
+ document.querySelectorAll('.dotgov-table__domain-requests th[data-sortable]').forEach(header => {
+ header.addEventListener('click', function() {
+ const sortBy = this.getAttribute('data-sortable');
+ let order = 'asc';
+ // sort order will be ascending, unless the currently sorted column is ascending, and the user
+ // is selecting the same column to sort in descending order
+ if (sortBy === currentSortBy) {
+ order = currentOrder === 'asc' ? 'desc' : 'asc';
+ }
+ loadDomainRequests(1, sortBy, order);
+ });
});
- });
- // Load the first page initially
- loadDomainRequests(1);
+ // Load the first page initially
+ loadDomainRequests(1);
+ }
});
diff --git a/src/registrar/views/domain_requests_json.py b/src/registrar/views/domain_requests_json.py
index 81dccefc2..319cbdea3 100644
--- a/src/registrar/views/domain_requests_json.py
+++ b/src/registrar/views/domain_requests_json.py
@@ -2,15 +2,13 @@ from django.http import JsonResponse
from django.core.paginator import Paginator
from registrar.models import DomainRequest
from django.utils.dateformat import format
+from django.contrib.auth.decorators import login_required
-
+@login_required
def get_domain_requests_json(request):
"""Given the current request,
get all domain requests that are associated with the request user and exclude the APPROVED ones"""
- if not request.user.is_authenticated:
- return JsonResponse({"error": "User not authenticated"}, status=401)
-
domain_requests = DomainRequest.objects.filter(creator=request.user).exclude(
status=DomainRequest.DomainRequestStatus.APPROVED
)
diff --git a/src/registrar/views/domains_json.py b/src/registrar/views/domains_json.py
index 52f886848..d0581ba64 100644
--- a/src/registrar/views/domains_json.py
+++ b/src/registrar/views/domains_json.py
@@ -1,15 +1,13 @@
from django.http import JsonResponse
from django.core.paginator import Paginator
from registrar.models import UserDomainRole, Domain
+from django.contrib.auth.decorators import login_required
-
+@login_required
def get_domains_json(request):
"""Given the current request,
get all domains that are associated with the UserDomainRole object"""
- if not request.user.is_authenticated:
- return JsonResponse({"error": "User not authenticated"}, status=401)
-
user_domain_roles = UserDomainRole.objects.filter(user=request.user)
domain_ids = user_domain_roles.values_list("domain_id", flat=True)