mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-27 19:43:43 +02:00
Add in checks for if theyre only admin or have any in progress requests
This commit is contained in:
parent
5f6e8968c7
commit
cd517ae885
3 changed files with 128 additions and 49 deletions
|
@ -2074,9 +2074,14 @@ class MembersTable extends LoadTableBase {
|
|||
modalHeading = `Are you sure you want to delete ${member_email}?`;
|
||||
modalDescription = `They will no longer be able to access this organization. \n
|
||||
This action cannot be undone.`;
|
||||
} else if (num_domains === 1) {
|
||||
modalHeading = `Are you sure you want to delete ${member_email}?`;
|
||||
modalDescription = `<b>${member_email}</b> currently manages ${num_domains} domain in the organization. \n
|
||||
Removing them from the organization will remove all of their domains. They will no longer be able to \n
|
||||
access this organization. This action cannot be undone.`;
|
||||
} else if (num_domains >= 1) {
|
||||
modalHeading = `Are you sure you want to delete ${member_email}?`;
|
||||
modalDescription = `${member_email} current manages ${num_domains} domains in the organization \n
|
||||
modalDescription = `<b>${member_email}</b> currently manages ${num_domains} domains in the organization. \n
|
||||
Removing them from the organization will remove all of their domains. They will no longer be able to \n
|
||||
access this organization. This action cannot be undone.`;
|
||||
}
|
||||
|
@ -2136,7 +2141,6 @@ class MembersTable extends LoadTableBase {
|
|||
</div>
|
||||
`
|
||||
this.tableWrapper.appendChild(modal);
|
||||
console.log("modal", modal)
|
||||
}
|
||||
|
||||
generateKebabHTML(member_id, member_name, last_active) {
|
||||
|
@ -2195,9 +2199,44 @@ class MembersTable extends LoadTableBase {
|
|||
* @param {*} domainRequestPk - the identifier for the request that we're deleting
|
||||
* @param {*} pageToDisplay - If we're deleting the last item on a page that is not page 1, we'll need to display the previous page
|
||||
*/
|
||||
// This is what we originally have
|
||||
// deleteMember(member_delete_url, pageToDisplay) {
|
||||
// // Use to debug uswds modal issues
|
||||
// console.log(member_delete_url)
|
||||
|
||||
// // Get csrf token
|
||||
// const csrfToken = getCsrfToken();
|
||||
// // Create FormData object and append the CSRF token
|
||||
// const formData = `csrfmiddlewaretoken=${encodeURIComponent(csrfToken)}`;
|
||||
|
||||
// fetch(`${member_delete_url}`, {
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/x-www-form-urlencoded',
|
||||
// 'X-CSRFToken': csrfToken,
|
||||
// },
|
||||
// body: formData
|
||||
|
||||
// })
|
||||
// .then(response => {
|
||||
// if (!response.ok) {
|
||||
// throw new Error(`HTTP error! status: ${response.status}`);
|
||||
// }
|
||||
// // Update data and UI
|
||||
// this.loadTable(pageToDisplay, this.currentSortBy, this.currentOrder, this.scrollToTable, this.currentSearchTerm);
|
||||
// })
|
||||
// .catch(error => console.error('Error fetching domain requests:', error));
|
||||
// }
|
||||
|
||||
deleteMember(member_delete_url, pageToDisplay) {
|
||||
// Use to debug uswds modal issues
|
||||
console.log(member_delete_url)
|
||||
// Debugging
|
||||
console.log(member_delete_url);
|
||||
|
||||
const inProgressResponse = "This member has an active domain request and can't \n"
|
||||
"be removed from this organization. <Contact the .gov team link> to remove them."
|
||||
const onlyAdminResponse = "There must be at least one admin in your organization. \n"
|
||||
"Give another member admin permissions, make sure they log into the registrar, \n"
|
||||
"and then remove this member."
|
||||
|
||||
// Get csrf token
|
||||
const csrfToken = getCsrfToken();
|
||||
|
@ -2211,44 +2250,40 @@ class MembersTable extends LoadTableBase {
|
|||
'X-CSRFToken': csrfToken,
|
||||
},
|
||||
body: formData
|
||||
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
if (response.status === 204) {
|
||||
// TODO: Add success alert with "You've removed member.email from the organization." text
|
||||
console.log('Member successfully deleted');
|
||||
// Update data and UI
|
||||
this.loadTable(pageToDisplay, this.currentSortBy, this.currentOrder, this.scrollToTable, this.currentSearchTerm);
|
||||
} else {
|
||||
// If the response isn't 204, handle the error response
|
||||
return response.json().then(data => {
|
||||
console.log("Member response not 204");
|
||||
if (data.error) {
|
||||
// TODO: We maybe don't need the consts above and have those
|
||||
// responses in the portfolios.py JSON response. Formatting though?
|
||||
|
||||
// This should display the error given from backend for
|
||||
// either only admin OR in progress requests
|
||||
this.displayErrorMessage(data.error);
|
||||
} else {
|
||||
throw new Error(`Unexpected status: ${response.status}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Update data and UI
|
||||
this.loadTable(pageToDisplay, this.currentSortBy, this.currentOrder, this.scrollToTable, this.currentSearchTerm);
|
||||
})
|
||||
.catch(error => console.error('Error fetching domain requests:', error));
|
||||
}
|
||||
.catch(error => {
|
||||
console.error('Error deleting member:', error);
|
||||
this.displayErrorMessage(error.message);
|
||||
});
|
||||
}
|
||||
|
||||
// deleteDomainRequest(domainRequestPk, pageToDisplay) {
|
||||
// // Use to debug uswds modal issues
|
||||
// //console.log('deleteDomainRequest')
|
||||
displayErrorMessage(errorMessage) {
|
||||
alert(errorMessage); // Just debugging for now
|
||||
}
|
||||
|
||||
// // Get csrf token
|
||||
// const csrfToken = getCsrfToken();
|
||||
// // Create FormData object and append the CSRF token
|
||||
// const formData = `csrfmiddlewaretoken=${encodeURIComponent(csrfToken)}&delete-domain-request=`;
|
||||
|
||||
// fetch(`/domain-request/${domainRequestPk}/delete`, {
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/x-www-form-urlencoded',
|
||||
// 'X-CSRFToken': csrfToken,
|
||||
// },
|
||||
// body: formData
|
||||
// })
|
||||
// .then(response => {
|
||||
// if (!response.ok) {
|
||||
// throw new Error(`HTTP error! status: ${response.status}`);
|
||||
// }
|
||||
// // Update data and UI
|
||||
// this.loadTable(pageToDisplay, this.currentSortBy, this.currentOrder, this.scrollToTable, this.currentSearchTerm);
|
||||
// })
|
||||
// .catch(error => console.error('Error fetching domain requests:', error));
|
||||
// }
|
||||
|
||||
/**
|
||||
* Loads rows in the members list, as well as updates pagination around the members list
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
|
||||
from django.apps import apps
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
|
@ -472,10 +473,41 @@ class User(AbstractUser):
|
|||
else:
|
||||
return UserDomainRole.objects.filter(user=self).values_list("id", flat=True)
|
||||
|
||||
# def get_user_domain_count(self, request):
|
||||
# """Returns the count of domains associated with this user on UserDomainRole or Portfolio"""
|
||||
# portfolio = request.session.get("portfolio")
|
||||
# if self.is_org_user(request) and self.has_view_all_domains_portfolio_permission(portfolio):
|
||||
# return DomainInformation.objects.filter(portfolio=portfolio).count()
|
||||
# else:
|
||||
# return UserDomainRole.objects.filter(user=self).count()
|
||||
def get_active_requests_count_in_portfolio(self, request):
|
||||
"""Return count of active requests for the portfolio associated with the request."""
|
||||
portfolio_id = request.session.get(
|
||||
"portfolio_id"
|
||||
) # Adjust based on how you store the portfolio ID in the session
|
||||
if not portfolio_id:
|
||||
return 0 # No portfolio ID found
|
||||
|
||||
allowed_states = [
|
||||
DomainRequest.DomainRequestStatus.SUBMITTED,
|
||||
DomainRequest.DomainRequestStatus.IN_REVIEW,
|
||||
DomainRequest.DomainRequestStatus.ACTION_NEEDED,
|
||||
]
|
||||
|
||||
# Assuming you have a way to filter domain requests by portfolio
|
||||
active_requests_count = self.domain_requests_created.filter(
|
||||
status__in=allowed_states, portfolio__id=portfolio_id # Ensure this field exists on the DomainRequest model
|
||||
).count()
|
||||
|
||||
return active_requests_count
|
||||
|
||||
def is_only_admin_of_portfolio(self, portfolio):
|
||||
"""Check if the user is the only admin of the given portfolio."""
|
||||
|
||||
UserPortfolioPermission = apps.get_model("registrar", "UserPortfolioPermission")
|
||||
|
||||
# Grab admin permission ability we want
|
||||
admin_permission = UserPortfolioPermissionChoices.EDIT_PORTFOLIO
|
||||
|
||||
# Get all users with admin permission for this portfolio
|
||||
admins = UserPortfolioPermission.objects.filter(portfolio=portfolio, roles__contains=[admin_permission])
|
||||
|
||||
# Check if there is more than one admin
|
||||
if admins.count() == 1 and admins.first().user == self:
|
||||
# The user is the only admin
|
||||
return True
|
||||
# There are other admins OR the user is not the only one
|
||||
return False
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import logging
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.http import HttpResponse, Http404, JsonResponse
|
||||
from django.shortcuts import render
|
||||
from django.urls import reverse
|
||||
from django.contrib import messages
|
||||
|
@ -100,6 +100,7 @@ class PortfolioMemberView(PortfolioMemberPermissionView, View):
|
|||
},
|
||||
)
|
||||
|
||||
|
||||
class PortfolioMemberDeleteView(PortfolioMemberPermission, View):
|
||||
|
||||
def post(self, request, pk):
|
||||
|
@ -108,6 +109,17 @@ class PortfolioMemberDeleteView(PortfolioMemberPermission, View):
|
|||
Redirect to a success page after deletion (or any other appropriate page).
|
||||
"""
|
||||
portfolio_member_permission = get_object_or_404(UserPortfolioPermission, pk=pk)
|
||||
member = portfolio_member_permission.user
|
||||
|
||||
active_requests_count = member.get_active_requests_count_in_portfolio(request)
|
||||
print(f"Active requests count for member {member.id}: {active_requests_count}")
|
||||
|
||||
if active_requests_count > 0:
|
||||
return JsonResponse({"error": "ERROR: Member has in-progress requests and cannot be removed."}, status=400)
|
||||
|
||||
# If they are the last manager of a domain
|
||||
if member.is_only_admin_of_portfolio(portfolio_member_permission.portfolio):
|
||||
return JsonResponse({"error": "ERROR: Member is the only admin."}, status=400)
|
||||
|
||||
portfolio_member_permission.delete()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue