Fix JS check, revise authentication check

This commit is contained in:
Rachid Mrad 2024-05-30 17:05:05 -04:00
parent 996a6944a3
commit fc52d98f21
No known key found for this signature in database
3 changed files with 333 additions and 331 deletions

View file

@ -912,180 +912,183 @@ function ScrollToElement(attributeName, attributeValue) {
* *
*/ */
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
let currentSortBy = 'id';
let currentOrder = 'asc';
let domainsWrapper = document.querySelector('.domains-wrapper'); let domainsWrapper = document.querySelector('.domains-wrapper');
let noDomainsWrapper = document.querySelector('.no-domains-wrapper');
let hasLoaded = false;
/** if (domainsWrapper) {
* Loads rows in the domains list, as well as updates pagination around the domains list let currentSortBy = 'id';
* based on the supplied attributes. let currentOrder = 'asc';
* @param {*} page - the page number of the results (starts with 1) let noDomainsWrapper = document.querySelector('.no-domains-wrapper');
* @param {*} sortBy - the sort column option let hasLoaded = false;
* @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;
}
// handle the display of proper messaging in the event that no domains exist in the list /**
if (data.domains.length) { * Loads rows in the domains list, as well as updates pagination around the domains list
domainsWrapper.classList.remove('display-none'); * based on the supplied attributes.
noDomainsWrapper.classList.add('display-none'); * @param {*} page - the page number of the results (starts with 1)
} else { * @param {*} sortBy - the sort column option
domainsWrapper.classList.add('display-none'); * @param {*} order - the sort order {asc, desc}
noDomainsWrapper.classList.remove('display-none'); * @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 // handle the display of proper messaging in the event that no domains exist in the list
const domainList = document.querySelector('.dotgov-table__registered-domains tbody'); if (data.domains.length) {
domainList.innerHTML = ''; 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 => { // identify the DOM element where the domain list will be inserted into the DOM
const expirationDate = domain.expiration_date ? new Date(domain.expiration_date) : null; const domainList = document.querySelector('.dotgov-table__registered-domains tbody');
const expirationDateSortValue = expirationDate ? expirationDate.getTime() : ''; domainList.innerHTML = '';
const actionUrl = domain.action_url;
const row = document.createElement('tr'); data.domains.forEach(domain => {
row.innerHTML = ` const expirationDate = domain.expiration_date ? new Date(domain.expiration_date) : null;
<th scope="row" role="rowheader" data-label="Domain name"> const expirationDateSortValue = expirationDate ? expirationDate.getTime() : '';
${domain.name} const actionUrl = domain.action_url;
</th>
<td data-sort-value="${expirationDateSortValue}" data-label="Expires"> const row = document.createElement('tr');
${expirationDate ? expirationDate.toLocaleDateString() : ''} row.innerHTML = `
</td> <th scope="row" role="rowheader" data-label="Domain name">
<td data-label="Status"> ${domain.name}
${domain.state_display} </th>
<svg <td data-sort-value="${expirationDateSortValue}" data-label="Expires">
class="usa-icon usa-tooltip usa-tooltip--registrar text-middle margin-bottom-05 text-accent-cool no-click-outline-and-cursor-help" ${expirationDate ? expirationDate.toLocaleDateString() : ''}
data-position="top" </td>
title="${domain.get_state_help_text}" <td data-label="Status">
focusable="true" ${domain.state_display}
aria-label="Status Information" <svg
role="tooltip" class="usa-icon usa-tooltip usa-tooltip--registrar text-middle margin-bottom-05 text-accent-cool no-click-outline-and-cursor-help"
> data-position="top"
<use aria-hidden="true" xlink:href="/public/img/sprite.svg#info_outline"></use> title="${domain.get_state_help_text}"
</svg> focusable="true"
</td> aria-label="Status Information"
<td> role="tooltip"
<a href="${actionUrl}"> >
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24"> <use aria-hidden="true" xlink:href="/public/img/sprite.svg#info_outline"></use>
<use xlink:href="/public/img/sprite.svg#${domain.state === 'deleted' || domain.state === 'on hold' ? 'visibility' : 'settings'}"></use>
</svg> </svg>
${domain.state === 'deleted' || domain.state === 'on hold' ? 'View' : 'Manage'} <span class="usa-sr-only">${domain.name}</span> </td>
</a> <td>
</td> <a href="${actionUrl}">
`; <svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24">
domainList.appendChild(row); <use xlink:href="/public/img/sprite.svg#${domain.state === 'deleted' || domain.state === 'on hold' ? 'visibility' : 'settings'}"></use>
}); </svg>
// initialize tool tips immediately after the associated DOM elements are added ${domain.state === 'deleted' || domain.state === 'on hold' ? 'View' : 'Manage'} <span class="usa-sr-only">${domain.name}</span>
initializeTooltips(); </a>
if (loaded) </td>
ScrollToElement('id', 'domains-header'); `;
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 // update pagination
updateDomainsPagination(data.page, data.num_pages, data.has_previous, data.has_next, data.total); updateDomainsPagination(data.page, data.num_pages, data.has_previous, data.has_next, data.total);
currentSortBy = sortBy; currentSortBy = sortBy;
currentOrder = order; currentOrder = order;
}) })
.catch(error => console.error('Error fetching domains:', error)); .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 = `
<a href="javascript:void(0);" class="usa-pagination__link usa-pagination__previous-page" aria-label="Domains previous page">
<svg class="usa-icon" aria-hidden="true" role="img">
<use xlink:href="/public/img/sprite.svg#navigate_before"></use>
</svg>
<span class="usa-pagination__link-text">Previous</span>
</a>
`;
prevPageItem.querySelector('a').addEventListener('click', () => loadDomains(currentPage - 1));
paginationButtons.appendChild(prevPageItem);
} }
for (let i = 1; i <= numPages; i++) { /**
const pageItem = document.createElement('li'); * Update the pagination below the domains list.
pageItem.className = 'usa-pagination__item usa-pagination__page-no'; * @param {*} currentPage - the current page number (starting with 1)
pageItem.innerHTML = ` * @param {*} numPages - the number of pages indicated by the domains list response
<a href="javascript:void(0);" class="usa-pagination__button" aria-label="Domains page ${i}">${i}</a> * @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
if (i === currentPage) { */
pageItem.querySelector('a').classList.add('usa-current'); function updateDomainsPagination(currentPage, numPages, hasPrevious, hasNext, totalItems) {
pageItem.querySelector('a').setAttribute('aria-current', 'page'); // 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 = `
<a href="javascript:void(0);" class="usa-pagination__link usa-pagination__previous-page" aria-label="Domains previous page">
<svg class="usa-icon" aria-hidden="true" role="img">
<use xlink:href="/public/img/sprite.svg#navigate_before"></use>
</svg>
<span class="usa-pagination__link-text">Previous</span>
</a>
`;
prevPageItem.querySelector('a').addEventListener('click', () => loadDomains(currentPage - 1));
paginationButtons.appendChild(prevPageItem);
} }
pageItem.querySelector('a').addEventListener('click', () => loadDomains(i));
paginationButtons.appendChild(pageItem);
}
if (hasNext) { for (let i = 1; i <= numPages; i++) {
const nextPageItem = document.createElement('li'); const pageItem = document.createElement('li');
nextPageItem.className = 'usa-pagination__item usa-pagination__arrow'; pageItem.className = 'usa-pagination__item usa-pagination__page-no';
nextPageItem.innerHTML = ` pageItem.innerHTML = `
<a href="javascript:void(0);" class="usa-pagination__link usa-pagination__next-page" aria-label="Domains next page"> <a href="javascript:void(0);" class="usa-pagination__button" aria-label="Domains page ${i}">${i}</a>
<span class="usa-pagination__link-text">Next</span> `;
<svg class="usa-icon" aria-hidden="true" role="img"> if (i === currentPage) {
<use xlink:href="/public/img/sprite.svg#navigate_next"></use> pageItem.querySelector('a').classList.add('usa-current');
</svg> pageItem.querySelector('a').setAttribute('aria-current', 'page');
</a> }
`; pageItem.querySelector('a').addEventListener('click', () => loadDomains(i));
nextPageItem.querySelector('a').addEventListener('click', () => loadDomains(currentPage + 1)); paginationButtons.appendChild(pageItem);
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); if (hasNext) {
const nextPageItem = document.createElement('li');
nextPageItem.className = 'usa-pagination__item usa-pagination__arrow';
nextPageItem.innerHTML = `
<a href="javascript:void(0);" class="usa-pagination__link usa-pagination__next-page" aria-label="Domains next page">
<span class="usa-pagination__link-text">Next</span>
<svg class="usa-icon" aria-hidden="true" role="img">
<use xlink:href="/public/img/sprite.svg#navigate_next"></use>
</svg>
</a>
`;
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 // Load the first page initially
loadDomains(1); loadDomains(1);
}
}); });
/** /**
@ -1094,185 +1097,188 @@ document.addEventListener('DOMContentLoaded', function() {
* *
*/ */
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
let currentSortBy = 'id';
let currentOrder = 'asc';
let domainRequestsWrapper = document.querySelector('.domain-requests-wrapper'); let domainRequestsWrapper = document.querySelector('.domain-requests-wrapper');
let noDomainRequestsWrapper = document.querySelector('.no-domain-requests-wrapper');
let hasLoaded = false;
/** if (domainRequestsWrapper) {
* Loads rows in the domain requests list, as well as updates pagination around the domain requests list let currentSortBy = 'id';
* based on the supplied attributes. let currentOrder = 'asc';
* @param {*} page - the page number of the results (starts with 1) let noDomainRequestsWrapper = document.querySelector('.no-domain-requests-wrapper');
* @param {*} sortBy - the sort column option let hasLoaded = false;
* @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;
}
// handle the display of proper messaging in the event that no domain requests exist in the list /**
if (data.domain_requests.length) { * Loads rows in the domain requests list, as well as updates pagination around the domain requests list
domainRequestsWrapper.classList.remove('display-none'); * based on the supplied attributes.
noDomainRequestsWrapper.classList.add('display-none'); * @param {*} page - the page number of the results (starts with 1)
} else { * @param {*} sortBy - the sort column option
domainRequestsWrapper.classList.add('display-none'); * @param {*} order - the sort order {asc, desc}
noDomainRequestsWrapper.classList.remove('display-none'); * @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 // handle the display of proper messaging in the event that no domain requests exist in the list
const tbody = document.querySelector('.dotgov-table__domain-requests tbody'); if (data.domain_requests.length) {
tbody.innerHTML = ''; 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 // identify the DOM element where the domain request list will be inserted into the DOM
// after the DOM content changes and there are new delete modal buttons added const tbody = document.querySelector('.dotgov-table__domain-requests tbody');
unloadModals(); tbody.innerHTML = '';
data.domain_requests.forEach(request => {
const domainName = request.requested_domain ? request.requested_domain : `New domain request <span class="text-base font-body-xs">(${new Date(request.created_at).toLocaleString()} UTC)</span>`;
const submissionDate = request.submission_date ? new Date(request.submission_date).toLocaleDateString() : `<span class="text-base">Not submitted</span>`;
const actionUrl = request.action_url;
const actionLabel = request.action_label;
const deleteButton = request.is_deletable ? `
<a
role="button"
id="button-toggle-delete-domain-alert-${request.id}"
href="#toggle-delete-domain-alert-${request.id}"
class="usa-button--unstyled text-no-underline late-loading-modal-trigger"
aria-controls="toggle-delete-domain-alert-${request.id}"
data-open-modal
>
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24">
<use xlink:href="/public/img/sprite.svg#delete"></use>
</svg> Delete <span class="usa-sr-only">${domainName}</span>
</a>` : '';
const row = document.createElement('tr'); // remove any existing modal elements from the DOM so they can be properly re-initialized
row.innerHTML = ` // after the DOM content changes and there are new delete modal buttons added
<th scope="row" role="rowheader" data-label="Domain name"> unloadModals();
${domainName} data.domain_requests.forEach(request => {
</th> const domainName = request.requested_domain ? request.requested_domain : `New domain request <span class="text-base font-body-xs">(${new Date(request.created_at).toLocaleString()} UTC)</span>`;
<td data-sort-value="${new Date(request.submission_date).getTime()}" data-label="Date submitted"> const submissionDate = request.submission_date ? new Date(request.submission_date).toLocaleDateString() : `<span class="text-base">Not submitted</span>`;
${submissionDate} const actionUrl = request.action_url;
</td> const actionLabel = request.action_label;
<td data-label="Status"> const deleteButton = request.is_deletable ? `
${request.status} <a
</td> role="button"
<td> id="button-toggle-delete-domain-alert-${request.id}"
<a href="${actionUrl}"> href="#toggle-delete-domain-alert-${request.id}"
class="usa-button--unstyled text-no-underline late-loading-modal-trigger"
aria-controls="toggle-delete-domain-alert-${request.id}"
data-open-modal
>
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24"> <svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24">
<use xlink:href="/public/img/sprite.svg#${request.state === 'deleted' || request.state === 'on hold' ? 'visibility' : 'settings'}"></use> <use xlink:href="/public/img/sprite.svg#delete"></use>
</svg> </svg> Delete <span class="usa-sr-only">${domainName}</span>
${actionLabel} <span class="usa-sr-only">${request.requested_domain ? request.requested_domain : 'New domain request'}</span> </a>` : '';
</a>
</td>
<td>${deleteButton}</td>
`;
tbody.appendChild(row);
});
// initialize modals immediately after the DOM content is updated
initializeModals();
if (loaded)
ScrollToElement('id', 'domain-requests-header');
hasLoaded = true; const row = document.createElement('tr');
row.innerHTML = `
<th scope="row" role="rowheader" data-label="Domain name">
${domainName}
</th>
<td data-sort-value="${new Date(request.submission_date).getTime()}" data-label="Date submitted">
${submissionDate}
</td>
<td data-label="Status">
${request.status}
</td>
<td>
<a href="${actionUrl}">
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24">
<use xlink:href="/public/img/sprite.svg#${request.state === 'deleted' || request.state === 'on hold' ? 'visibility' : 'settings'}"></use>
</svg>
${actionLabel} <span class="usa-sr-only">${request.requested_domain ? request.requested_domain : 'New domain request'}</span>
</a>
</td>
<td>${deleteButton}</td>
`;
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 hasLoaded = true;
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));
}
/** // update the pagination after the domain requests list is updated
* Update the pagination below the domain requests list. updateDomainRequestsPagination(data.page, data.num_pages, data.has_previous, data.has_next, data.total);
* @param {*} currentPage - the current page number (starting with 1) currentSortBy = sortBy;
* @param {*} numPages - the number of pages indicated by the domain request list response currentOrder = order;
* @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 .catch(error => console.error('Error fetching domain requests:', error));
*/
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 = `
<a href="javascript:void(0);" class="usa-pagination__link usa-pagination__previous-page" aria-label="Domain requests previous page">
<svg class="usa-icon" aria-hidden="true" role="img">
<use xlink:href="/public/img/sprite.svg#navigate_before"></use>
</svg>
<span class="usa-pagination__link-text">Previous</span>
</a>
`;
prevPageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(currentPage - 1));
paginationButtons.appendChild(prevPageItem);
} }
for (let i = 1; i <= numPages; i++) { /**
const pageItem = document.createElement('li'); * Update the pagination below the domain requests list.
pageItem.className = 'usa-pagination__item usa-pagination__page-no'; * @param {*} currentPage - the current page number (starting with 1)
pageItem.innerHTML = ` * @param {*} numPages - the number of pages indicated by the domain request list response
<a href="javascript:void(0);" class="usa-pagination__button" aria-label="Domain requests page ${i}">${i}</a> * @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
if (i === currentPage) { */
pageItem.querySelector('a').classList.add('usa-current'); function updateDomainRequestsPagination(currentPage, numPages, hasPrevious, hasNext, totalItems) {
pageItem.querySelector('a').setAttribute('aria-current', 'page'); // 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 = `
<a href="javascript:void(0);" class="usa-pagination__link usa-pagination__previous-page" aria-label="Domain requests previous page">
<svg class="usa-icon" aria-hidden="true" role="img">
<use xlink:href="/public/img/sprite.svg#navigate_before"></use>
</svg>
<span class="usa-pagination__link-text">Previous</span>
</a>
`;
prevPageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(currentPage - 1));
paginationButtons.appendChild(prevPageItem);
} }
pageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(i));
paginationButtons.appendChild(pageItem);
}
if (hasNext) { for (let i = 1; i <= numPages; i++) {
const nextPageItem = document.createElement('li'); const pageItem = document.createElement('li');
nextPageItem.className = 'usa-pagination__item usa-pagination__arrow'; pageItem.className = 'usa-pagination__item usa-pagination__page-no';
nextPageItem.innerHTML = ` pageItem.innerHTML = `
<a href="javascript:void(0);" class="usa-pagination__link usa-pagination__next-page" aria-label="Domain requests next page"> <a href="javascript:void(0);" class="usa-pagination__button" aria-label="Domain requests page ${i}">${i}</a>
<span class="usa-pagination__link-text">Next</span> `;
<svg class="usa-icon" aria-hidden="true" role="img"> if (i === currentPage) {
<use xlink:href="/public/img/sprite.svg#navigate_next"></use> pageItem.querySelector('a').classList.add('usa-current');
</svg> pageItem.querySelector('a').setAttribute('aria-current', 'page');
</a> }
`; pageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(i));
nextPageItem.querySelector('a').addEventListener('click', () => loadDomainRequests(currentPage + 1)); paginationButtons.appendChild(pageItem);
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);
if (hasNext) {
const nextPageItem = document.createElement('li');
nextPageItem.className = 'usa-pagination__item usa-pagination__arrow';
nextPageItem.innerHTML = `
<a href="javascript:void(0);" class="usa-pagination__link usa-pagination__next-page" aria-label="Domain requests next page">
<span class="usa-pagination__link-text">Next</span>
<svg class="usa-icon" aria-hidden="true" role="img">
<use xlink:href="/public/img/sprite.svg#navigate_next"></use>
</svg>
</a>
`;
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 // Load the first page initially
loadDomainRequests(1); loadDomainRequests(1);
}
}); });

View file

@ -2,15 +2,13 @@ from django.http import JsonResponse
from django.core.paginator import Paginator from django.core.paginator import Paginator
from registrar.models import DomainRequest from registrar.models import DomainRequest
from django.utils.dateformat import format from django.utils.dateformat import format
from django.contrib.auth.decorators import login_required
@login_required
def get_domain_requests_json(request): def get_domain_requests_json(request):
"""Given the current request, """Given the current request,
get all domain requests that are associated with the request user and exclude the APPROVED ones""" 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( domain_requests = DomainRequest.objects.filter(creator=request.user).exclude(
status=DomainRequest.DomainRequestStatus.APPROVED status=DomainRequest.DomainRequestStatus.APPROVED
) )

View file

@ -1,15 +1,13 @@
from django.http import JsonResponse from django.http import JsonResponse
from django.core.paginator import Paginator from django.core.paginator import Paginator
from registrar.models import UserDomainRole, Domain from registrar.models import UserDomainRole, Domain
from django.contrib.auth.decorators import login_required
@login_required
def get_domains_json(request): def get_domains_json(request):
"""Given the current request, """Given the current request,
get all domains that are associated with the UserDomainRole object""" 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) user_domain_roles = UserDomainRole.objects.filter(user=request.user)
domain_ids = user_domain_roles.values_list("domain_id", flat=True) domain_ids = user_domain_roles.values_list("domain_id", flat=True)