mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-22 01:01:08 +02:00
modified userportfoliopermissions and portfolioinvitation admin forms
This commit is contained in:
parent
260d2e587f
commit
3434519a16
7 changed files with 167 additions and 65 deletions
|
@ -192,7 +192,16 @@ class MyUserAdminForm(UserChangeForm):
|
|||
)
|
||||
|
||||
|
||||
class UserPortfolioPermissionsForm(forms.ModelForm):
|
||||
class PortfolioPermissionsForm(forms.ModelForm):
|
||||
"""
|
||||
Form for managing portfolio permissions in Django admin. This form class is used
|
||||
for both UserPortfolioPermission and PortfolioInvitation models.
|
||||
|
||||
Allows selecting a portfolio, assigning a role, and managing specific permissions
|
||||
related to requests, domains, and members.
|
||||
"""
|
||||
|
||||
# Define available permissions for requests, domains, and members
|
||||
REQUEST_PERMISSIONS = [
|
||||
UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS,
|
||||
UserPortfolioPermissionChoices.EDIT_REQUESTS,
|
||||
|
@ -207,111 +216,134 @@ class UserPortfolioPermissionsForm(forms.ModelForm):
|
|||
UserPortfolioPermissionChoices.VIEW_MEMBERS,
|
||||
]
|
||||
|
||||
user = forms.ModelChoiceField(
|
||||
queryset=models.User.objects.all(),
|
||||
label="User"
|
||||
)
|
||||
|
||||
portfolio = forms.ModelChoiceField(
|
||||
queryset=models.Portfolio.objects.all(),
|
||||
label="Portfolio"
|
||||
)
|
||||
# Dropdown to select a portfolio
|
||||
portfolio = forms.ModelChoiceField(queryset=models.Portfolio.objects.all(), label="Portfolio")
|
||||
|
||||
# Dropdown for selecting the user role (e.g., Admin or Basic)
|
||||
role = forms.ChoiceField(
|
||||
choices=UserPortfolioRoleChoices.choices,
|
||||
required=True,
|
||||
widget=forms.Select(attrs={"class": "admin-dropdown"}),
|
||||
label="Member access"
|
||||
label="Member access",
|
||||
)
|
||||
|
||||
# Dropdown for selecting request permissions, with a default "No access" option
|
||||
request_permissions = forms.ChoiceField(
|
||||
choices=[(perm.value, perm.label) for perm in REQUEST_PERMISSIONS],
|
||||
choices=[(None, "No access")] + [(perm.value, perm.label) for perm in REQUEST_PERMISSIONS],
|
||||
required=False,
|
||||
widget=forms.Select(attrs={"class": "admin-dropdown"}),
|
||||
label="Domain requests"
|
||||
label="Domain requests",
|
||||
)
|
||||
|
||||
# Dropdown for selecting domain permissions
|
||||
domain_permissions = forms.ChoiceField(
|
||||
choices=[(perm.value, perm.label) for perm in DOMAIN_PERMISSIONS],
|
||||
required=False,
|
||||
widget=forms.Select(attrs={"class": "admin-dropdown"}),
|
||||
label="Domains"
|
||||
label="Domains",
|
||||
)
|
||||
|
||||
# Dropdown for selecting member permissions, with a default "No access" option
|
||||
member_permissions = forms.ChoiceField(
|
||||
choices=[(perm.value, perm.label) for perm in MEMBER_PERMISSIONS],
|
||||
choices=[(None, "No access")] + [(perm.value, perm.label) for perm in MEMBER_PERMISSIONS],
|
||||
required=False,
|
||||
widget=forms.Select(attrs={"class": "admin-dropdown"}),
|
||||
label="Members"
|
||||
label="Members",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = models.UserPortfolioPermission
|
||||
fields = ["user", "portfolio", "role", "domain_permissions", "request_permissions", "member_permissions"]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Initialize the form and set default values based on the existing instance.
|
||||
"""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
logger.debug("Initializing form")
|
||||
|
||||
# Populate roles
|
||||
# If an instance exists, populate the form fields with existing data
|
||||
if self.instance and self.instance.pk:
|
||||
# Set the initial value for the role field
|
||||
if self.instance.roles:
|
||||
logger.debug(f"Setting role: {self.instance.roles[0]}")
|
||||
self.fields["role"].initial = self.instance.roles[0] # Assuming single role per user
|
||||
self.fields["role"].initial = self.instance.roles[0] # Assuming a single role per user
|
||||
|
||||
# Set the initial values for permissions based on the instance data
|
||||
if self.instance.additional_permissions:
|
||||
logger.debug(f"Existing permissions: {self.instance.additional_permissions}")
|
||||
for perm in self.instance.additional_permissions:
|
||||
logger.debug(f"Processing permission: {perm}")
|
||||
if perm in self.REQUEST_PERMISSIONS:
|
||||
logger.debug("Assigning request permission")
|
||||
self.fields["request_permissions"].initial = perm
|
||||
elif perm in self.DOMAIN_PERMISSIONS:
|
||||
logger.debug("Assigning domain permission")
|
||||
self.fields["domain_permissions"].initial = perm
|
||||
elif perm in self.MEMBER_PERMISSIONS:
|
||||
logger.debug("Assigning member permission")
|
||||
self.fields["member_permissions"].initial = perm
|
||||
|
||||
def clean(self):
|
||||
"""
|
||||
Custom validation and processing of form data before saving.
|
||||
"""
|
||||
cleaned_data = super().clean()
|
||||
|
||||
# Store the selected role as a list (assuming single role assignment)
|
||||
self.instance.roles = [cleaned_data.get("role")] if cleaned_data.get("role") else []
|
||||
logger.debug(f"Cleaned roles: {self.instance.roles}")
|
||||
|
||||
# If the selected role is "organization_member," store additional permissions
|
||||
if self.instance.roles == [UserPortfolioRoleChoices.ORGANIZATION_MEMBER]:
|
||||
self.instance.additional_permissions = list(
|
||||
filter(None, [
|
||||
filter(
|
||||
None,
|
||||
[
|
||||
cleaned_data.get("request_permissions"),
|
||||
cleaned_data.get("domain_permissions"),
|
||||
cleaned_data.get("member_permissions"),
|
||||
])
|
||||
],
|
||||
)
|
||||
)
|
||||
else:
|
||||
# If the user is an admin, clear any additional permissions
|
||||
self.instance.additional_permissions = []
|
||||
|
||||
logger.debug(f"Final saved permissions: {self.instance.additional_permissions}")
|
||||
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class PortfolioInvitationAdminForm(UserChangeForm):
|
||||
"""This form utilizes the custom widget for its class's ManyToMany UIs."""
|
||||
class UserPortfolioPermissionsForm(PortfolioPermissionsForm):
|
||||
"""
|
||||
Form for managing user portfolio permissions in Django admin.
|
||||
|
||||
Extends PortfolioPermissionsForm to include a user field, allowing administrators
|
||||
to assign roles and permissions to specific users within a portfolio.
|
||||
"""
|
||||
|
||||
# Dropdown to select a user from the database
|
||||
user = forms.ModelChoiceField(queryset=models.User.objects.all(), label="User")
|
||||
|
||||
class Meta:
|
||||
model = models.PortfolioInvitation
|
||||
fields = "__all__"
|
||||
widgets = {
|
||||
"roles": FilteredSelectMultipleArrayWidget(
|
||||
"roles", is_stacked=False, choices=UserPortfolioRoleChoices.choices
|
||||
),
|
||||
"additional_permissions": FilteredSelectMultipleArrayWidget(
|
||||
"additional_permissions",
|
||||
is_stacked=False,
|
||||
choices=UserPortfolioPermissionChoices.choices,
|
||||
),
|
||||
}
|
||||
"""
|
||||
Meta class defining the model and fields to be used in the form.
|
||||
"""
|
||||
|
||||
model = models.UserPortfolioPermission # Uses the UserPortfolioPermission model
|
||||
fields = ["user", "portfolio", "role", "domain_permissions", "request_permissions", "member_permissions"]
|
||||
|
||||
|
||||
class PortfolioInvitationForm(PortfolioPermissionsForm):
|
||||
"""
|
||||
Form for sending portfolio invitations in Django admin.
|
||||
|
||||
Extends PortfolioPermissionsForm to include an email field for inviting users,
|
||||
allowing them to be assigned a role and permissions within a portfolio before they join.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
Meta class defining the model and fields to be used in the form.
|
||||
"""
|
||||
|
||||
model = models.PortfolioInvitation # Uses the PortfolioInvitation model
|
||||
fields = [
|
||||
"email",
|
||||
"portfolio",
|
||||
"role",
|
||||
"domain_permissions",
|
||||
"request_permissions",
|
||||
"member_permissions",
|
||||
"status",
|
||||
]
|
||||
|
||||
|
||||
class DomainInformationAdminForm(forms.ModelForm):
|
||||
|
@ -1721,7 +1753,7 @@ class DomainInvitationAdmin(BaseInvitationAdmin):
|
|||
class PortfolioInvitationAdmin(BaseInvitationAdmin):
|
||||
"""Custom portfolio invitation admin class."""
|
||||
|
||||
form = PortfolioInvitationAdminForm
|
||||
form = PortfolioInvitationForm
|
||||
|
||||
class Meta:
|
||||
model = models.PortfolioInvitation
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
initDynamicDomainRequestFields } from './domain-request-form.js';
|
||||
import { initDomainFormTargetBlankButtons } from './domain-form.js';
|
||||
import { initDynamicPortfolioFields } from './portfolio-form.js';
|
||||
import { initDynamicPortfolioPermissionFields } from './portfolio-permissions-form.js'
|
||||
import { initDynamicDomainInformationFields } from './domain-information-form.js';
|
||||
import { initDynamicDomainFields } from './domain-form.js';
|
||||
import { initAnalyticsDashboard } from './analytics.js';
|
||||
|
@ -40,6 +41,9 @@ initDynamicDomainFields();
|
|||
// Portfolio
|
||||
initDynamicPortfolioFields();
|
||||
|
||||
// Portfolio permissions
|
||||
initDynamicPortfolioPermissionFields();
|
||||
|
||||
// Domain information
|
||||
initDynamicDomainInformationFields();
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
import { hideElement, showElement } from './helpers-admin.js';
|
||||
|
||||
/**
|
||||
* A function for dynamically changing fields on the UserPortfolioPermissions
|
||||
* and PortfolioInvitation admin forms
|
||||
*/
|
||||
function handlePortfolioPermissionFields(){
|
||||
|
||||
const roleDropdown = document.getElementById("id_role");
|
||||
const domainPermissionsField = document.querySelector(".field-domain_permissions");
|
||||
const domainRequestPermissionsField = document.querySelector(".field-request_permissions");
|
||||
const memberPermissionsField = document.querySelector(".field-member_permissions");
|
||||
|
||||
/**
|
||||
* Updates the visibility of portfolio permissions fields based on the selected role.
|
||||
*
|
||||
* This function checks the value of the role dropdown (`roleDropdown`):
|
||||
* - If the selected role is "organization_admin":
|
||||
* - Hides the domain permissions field (`domainPermissionsField`).
|
||||
* - Hides the domain request permissions field (`domainRequestPermissionsField`).
|
||||
* - Hides the member permissions field (`memberPermissionsField`).
|
||||
* - Otherwise:
|
||||
* - Shows all the above fields.
|
||||
*
|
||||
* The function ensures that the appropriate fields are dynamically displayed
|
||||
* or hidden depending on the role selection in the form.
|
||||
*/
|
||||
function updatePortfolioPermissionsFormVisibility() {
|
||||
if (roleDropdown && domainPermissionsField && domainRequestPermissionsField && memberPermissionsField) {
|
||||
if (roleDropdown.value === "organization_admin") {
|
||||
hideElement(domainPermissionsField);
|
||||
hideElement(domainRequestPermissionsField);
|
||||
hideElement(memberPermissionsField);
|
||||
} else {
|
||||
showElement(domainPermissionsField);
|
||||
showElement(domainRequestPermissionsField);
|
||||
showElement(memberPermissionsField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets event listeners for key UI elements.
|
||||
*/
|
||||
function setEventListeners() {
|
||||
if (roleDropdown) {
|
||||
roleDropdown.addEventListener("change", function() {
|
||||
updatePortfolioPermissionsFormVisibility();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Run initial setup functions
|
||||
updatePortfolioPermissionsFormVisibility();
|
||||
setEventListeners();
|
||||
}
|
||||
|
||||
export function initDynamicPortfolioPermissionFields() {
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
let isPortfolioPermissionPage = document.getElementById("userportfoliopermission_form");
|
||||
let isPortfolioInvitationPage = document.getElementById("portfolioinvitation_form")
|
||||
if (isPortfolioPermissionPage || isPortfolioInvitationPage) {
|
||||
handlePortfolioPermissionFields();
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
""""
|
||||
"""
|
||||
Converts all ready and DNS needed domains with a non-default public contact
|
||||
to disclose their public contact. Created for Issue#1535 to resolve
|
||||
disclose issue of domains with missing security emails.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
"""Data migration:
|
||||
1 - generates a report of data integrity across all
|
||||
transition domain related tables
|
||||
2 - allows users to run all migration scripts for
|
||||
transition domain data
|
||||
1 - generates a report of data integrity across all
|
||||
transition domain related tables
|
||||
2 - allows users to run all migration scripts for
|
||||
transition domain data
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
""""
|
||||
"""
|
||||
Data migration: Renaming deprecated Federal Agencies to
|
||||
their new updated names ie (U.S. Peace Corps to Peace Corps)
|
||||
within Domain Information and Domain Requests
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"""Views for a User Profile.
|
||||
"""
|
||||
"""Views for a User Profile."""
|
||||
|
||||
import logging
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue