mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-06-06 20:45:36 +02:00
Fix migrations + readonly views
This commit is contained in:
parent
afe498978c
commit
280bc23fa6
10 changed files with 118 additions and 13 deletions
|
@ -1242,8 +1242,10 @@ class UserDomainRoleResource(resources.ModelResource):
|
||||||
model = models.UserDomainRole
|
model = models.UserDomainRole
|
||||||
|
|
||||||
|
|
||||||
|
# Note: This is "viewonly" for analysts
|
||||||
class UserPortfolioPermissionAdmin(ListHeaderAdmin):
|
class UserPortfolioPermissionAdmin(ListHeaderAdmin):
|
||||||
form = UserPortfolioPermissionsForm
|
form = UserPortfolioPermissionsForm
|
||||||
|
change_form_template = "django/admin/user_portfolio_permission_change_form.html"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Contains meta information about this class"""
|
"""Contains meta information about this class"""
|
||||||
|
@ -1261,6 +1263,14 @@ class UserPortfolioPermissionAdmin(ListHeaderAdmin):
|
||||||
|
|
||||||
autocomplete_fields = ["user", "portfolio"]
|
autocomplete_fields = ["user", "portfolio"]
|
||||||
|
|
||||||
|
def change_view(self, request, object_id, form_url="", extra_context=None):
|
||||||
|
"""Adds a readonly display for roles and permissions"""
|
||||||
|
obj = self.get_object(request, object_id)
|
||||||
|
extra_context = extra_context or {}
|
||||||
|
extra_context["display_roles"] = ", ".join(obj.get_readable_roles())
|
||||||
|
extra_context["display_permissions"] = ", ".join(obj.get_readable_additional_permissions())
|
||||||
|
return super().change_view(request, object_id, form_url, extra_context)
|
||||||
|
|
||||||
|
|
||||||
class UserDomainRoleAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
class UserDomainRoleAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
"""Custom user domain role admin class."""
|
"""Custom user domain role admin class."""
|
||||||
|
@ -2961,7 +2971,6 @@ class PortfolioAdmin(ListHeaderAdmin):
|
||||||
|
|
||||||
analyst_readonly_fields = [
|
analyst_readonly_fields = [
|
||||||
"organization_name",
|
"organization_name",
|
||||||
"organization_type",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_readonly_fields(self, request, obj=None):
|
def get_readonly_fields(self, request, obj=None):
|
||||||
|
|
|
@ -858,11 +858,13 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
// $ symbolically denotes that this is using jQuery
|
// $ symbolically denotes that this is using jQuery
|
||||||
let $federalAgency = django.jQuery("#id_federal_agency");
|
let $federalAgency = django.jQuery("#id_federal_agency");
|
||||||
let organizationType = document.getElementById("id_organization_type");
|
let organizationType = document.getElementById("id_organization_type");
|
||||||
|
let readonlyOrganizationType = document.querySelector(".field-organization_type .readonly");
|
||||||
|
|
||||||
let federalType = document.getElementById("id_federal_type")
|
let federalType = document.getElementById("id_federal_type")
|
||||||
if ($federalAgency && organizationType && federalType) {
|
if ($federalAgency && (organizationType || readonlyOrganizationType) && federalType) {
|
||||||
// Attach the change event listener
|
// Attach the change event listener
|
||||||
$federalAgency.on("change", function() {
|
$federalAgency.on("change", function() {
|
||||||
handleFederalAgencyChange($federalAgency, organizationType, federalType);
|
handleFederalAgencyChange($federalAgency, organizationType, readonlyOrganizationType, federalType);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,7 +882,7 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleFederalAgencyChange(federalAgency, organizationType, federalType) {
|
function handleFederalAgencyChange(federalAgency, organizationType, readonlyOrganizationType, federalType) {
|
||||||
// Don't do anything on page load
|
// Don't do anything on page load
|
||||||
if (isInitialPageLoad) {
|
if (isInitialPageLoad) {
|
||||||
isInitialPageLoad = false;
|
isInitialPageLoad = false;
|
||||||
|
@ -895,13 +897,22 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let organizationTypeValue = organizationType ? organizationType.value : readonlyOrganizationType.innerText.toLowerCase();
|
||||||
if (selectedText !== "Non-Federal Agency") {
|
if (selectedText !== "Non-Federal Agency") {
|
||||||
if (organizationType.value !== "federal") {
|
if (organizationTypeValue !== "federal") {
|
||||||
organizationType.value = "federal";
|
if (organizationType){
|
||||||
|
organizationType.value = "federal";
|
||||||
|
}else {
|
||||||
|
readonlyOrganizationType.innerText = "Federal"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
if (organizationType.value === "federal") {
|
if (organizationTypeValue === "federal") {
|
||||||
organizationType.value = "";
|
if (organizationType){
|
||||||
|
organizationType.value = "";
|
||||||
|
}else {
|
||||||
|
readonlyOrganizationType.innerText = "-"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,10 +923,12 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
organizationTypeValue = organizationType ? organizationType.value : readonlyOrganizationType.innerText.toLowerCase();
|
||||||
|
|
||||||
// Determine if any changes are necessary to the display of portfolio type or federal type
|
// Determine if any changes are necessary to the display of portfolio type or federal type
|
||||||
// based on changes to the Federal Agency
|
// based on changes to the Federal Agency
|
||||||
let federalPortfolioApi = document.getElementById("federal_and_portfolio_types_from_agency_json_url").value;
|
let federalPortfolioApi = document.getElementById("federal_and_portfolio_types_from_agency_json_url").value;
|
||||||
fetch(`${federalPortfolioApi}?organization_type=${organizationType.value}&agency_name=${selectedText}`)
|
fetch(`${federalPortfolioApi}?organization_type=${organizationTypeValue}&agency_name=${selectedText}`)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
const statusCode = response.status;
|
const statusCode = response.status;
|
||||||
return response.json().then(data => ({ statusCode, data }));
|
return response.json().then(data => ({ statusCode, data }));
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.db import migrations, models
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("registrar", "0128_create_groups_v17"),
|
("registrar", "0128_alter_domaininformation_state_territory_and_more"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
@ -25,7 +25,7 @@ def create_groups(apps, schema_editor) -> Any:
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("registrar", "0127_remove_domaininformation_submitter_and_more"),
|
("registrar", "0129_portfolio_federal_type"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
|
@ -79,7 +79,7 @@ class UserGroup(Group):
|
||||||
{
|
{
|
||||||
"app_label": "registrar",
|
"app_label": "registrar",
|
||||||
"model": "userportfoliopermission",
|
"model": "userportfoliopermission",
|
||||||
"permissions": ["add_userportfoliopermission", "change_userportfoliopermission", "delete_userportfoliopermission"],
|
"permissions": ["view_userportfoliopermission"],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,24 @@ class UserPortfolioPermission(TimeStampedModel):
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"User '{self.user}' on Portfolio '{self.portfolio}' " f"<Roles: {self.roles}>" if self.roles else ""
|
readable_roles = []
|
||||||
|
if self.roles:
|
||||||
|
readable_roles = sorted([UserPortfolioRoleChoices.get_user_portfolio_role_label(role) for role in self.roles])
|
||||||
|
return f"{self.user}' " f"<Roles: {', '.join(readable_roles)}>" if self.roles else ""
|
||||||
|
|
||||||
|
def get_readable_roles(self):
|
||||||
|
"""Returns a list of labels of each role in self.roles"""
|
||||||
|
role_labels = []
|
||||||
|
for role in self.roles:
|
||||||
|
role_labels.append(UserPortfolioRoleChoices.get_user_portfolio_role_label(role))
|
||||||
|
return role_labels
|
||||||
|
|
||||||
|
def get_readable_additional_permissions(self):
|
||||||
|
"""Returns a list of labels of each additional_permission in self.additional_permissions"""
|
||||||
|
perm_labels = []
|
||||||
|
for perm in self.additional_permissions:
|
||||||
|
perm_labels.append(UserPortfolioPermissionChoices.get_user_portfolio_permission_label(perm))
|
||||||
|
return perm_labels
|
||||||
|
|
||||||
def _get_portfolio_permissions(self):
|
def _get_portfolio_permissions(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -10,6 +10,10 @@ class UserPortfolioRoleChoices(models.TextChoices):
|
||||||
ORGANIZATION_ADMIN_READ_ONLY = "organization_admin_read_only", "Admin read only"
|
ORGANIZATION_ADMIN_READ_ONLY = "organization_admin_read_only", "Admin read only"
|
||||||
ORGANIZATION_MEMBER = "organization_member", "Member"
|
ORGANIZATION_MEMBER = "organization_member", "Member"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_user_portfolio_role_label(cls, user_portfolio_role):
|
||||||
|
return cls(user_portfolio_role).label if user_portfolio_role else None
|
||||||
|
|
||||||
|
|
||||||
class UserPortfolioPermissionChoices(models.TextChoices):
|
class UserPortfolioPermissionChoices(models.TextChoices):
|
||||||
""" """
|
""" """
|
||||||
|
@ -29,3 +33,7 @@ class UserPortfolioPermissionChoices(models.TextChoices):
|
||||||
# Domain: field specific permissions
|
# Domain: field specific permissions
|
||||||
VIEW_SUBORGANIZATION = "view_suborganization", "View suborganization"
|
VIEW_SUBORGANIZATION = "view_suborganization", "View suborganization"
|
||||||
EDIT_SUBORGANIZATION = "edit_suborganization", "Edit suborganization"
|
EDIT_SUBORGANIZATION = "edit_suborganization", "Edit suborganization"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_user_portfolio_permission_label(cls, user_portfolio_permission):
|
||||||
|
return cls(user_portfolio_permission).label if user_portfolio_permission else None
|
|
@ -13,6 +13,22 @@
|
||||||
<p>No additional members found.</p>
|
<p>No additional members found.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
{% elif field.field.name == "roles" %}
|
||||||
|
<div class="readonly">
|
||||||
|
{% if get_readable_roles %}
|
||||||
|
{{ get_readable_roles }}
|
||||||
|
{% else %}
|
||||||
|
<p>No roles found.</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% elif field.field.name == "additional_permissions" %}
|
||||||
|
<div class="readonly">
|
||||||
|
{% if display_permissions %}
|
||||||
|
{{ display_permissions }}
|
||||||
|
{% else %}
|
||||||
|
<p>No additional permissions found.</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="readonly">{{ field.contents }}</div>
|
<div class="readonly">{{ field.contents }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
{% extends "django/admin/includes/detail_table_fieldset.html" %}
|
||||||
|
{% load custom_filters %}
|
||||||
|
{% load static url_helpers %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block field_readonly %}
|
||||||
|
{% if field.field.name == "roles" %}
|
||||||
|
<div class="readonly">
|
||||||
|
{% if display_roles %}
|
||||||
|
{{ display_roles }}
|
||||||
|
{% else %}
|
||||||
|
No roles found.
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% elif field.field.name == "additional_permissions" %}
|
||||||
|
<div class="readonly">
|
||||||
|
{% if display_permissions %}
|
||||||
|
{{ display_permissions }}
|
||||||
|
{% else %}
|
||||||
|
No additional permissions found.
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="readonly">{{ field.contents }}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock field_readonly%}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{% extends 'django/admin/email_clipboard_change_form.html' %}
|
||||||
|
{% load custom_filters %}
|
||||||
|
{% load i18n static %}
|
||||||
|
|
||||||
|
{% block field_sets %}
|
||||||
|
{% for fieldset in adminform %}
|
||||||
|
{% comment %}
|
||||||
|
This is a placeholder for now.
|
||||||
|
|
||||||
|
Disclaimer:
|
||||||
|
When extending the fieldset view consider whether you need to make a new one that extends from detail_table_fieldset.
|
||||||
|
detail_table_fieldset is used on multiple admin pages, so a change there can have unintended consequences.
|
||||||
|
{% endcomment %}
|
||||||
|
{% include "django/admin/includes/user_portfolio_permission_fieldset.html" with original_object=original %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
Loading…
Add table
Add a link
Reference in a new issue