diff --git a/coldfront/core/allocation/templates/allocation/cluster_access_badge.html b/coldfront/core/allocation/templates/allocation/cluster_access_badge.html new file mode 100644 index 000000000..99bf926b5 --- /dev/null +++ b/coldfront/core/allocation/templates/allocation/cluster_access_badge.html @@ -0,0 +1,48 @@ +{% comment %} + +Display a badge, info icon, and popup denoting a user's access to the cluster +under a project, based on a string `status`, which is expected to be one of the +following values: + +"Active" +"Pending - Add" +"Pending - Remove" +"Denied" +"None" + +If a different value is given, display an "Error" badge. + +Usage: {% include "allocation/cluster_access_badge.html" with status="status" %} + +{% endcomment %} + +{% if status == "Active" %} + + Active + +{% elif status == "Pending - Add" %} + + Pending + + {% include "portal/info_hover_popup.html" with title="Pending" content="Administrators will review the user's request to access the project on the cluster, and configure their cluster account accordingly." %} +{% elif status == "Pending - Remove" %} + + Pending Removal + + {% include "portal/info_hover_popup.html" with title="Pending Removal" content="The user is being removed from the project. Administrators will configure their cluster account accordingly." %} +{% elif status == "Denied" %} + + Denied + + {% include "portal/info_hover_popup.html" with title="Denied" content="Administrators have denied the user's request to access the project on the cluster. Please contact us for further assistance." %} +{% elif status == "None" %} + + No Access + + {% include "portal/info_hover_popup.html" with title="No Access" content="The user has not requested access to the project on the cluster." %} +{% else %} + + Error + + {% include "portal/info_hover_popup.html" with title="Error" content="Error. Please contact an administrator." %} +{% endif %} diff --git a/coldfront/core/allocation/utils.py b/coldfront/core/allocation/utils.py index 4566ea253..a328e6eab 100644 --- a/coldfront/core/allocation/utils.py +++ b/coldfront/core/allocation/utils.py @@ -153,13 +153,6 @@ def set_allocation_user_attribute_value(allocation_user_obj, type_name, value): return allocation_user_attribute -def get_allocation_user_cluster_access_status(allocation_obj, user_obj): - return allocation_obj.allocationuserattribute_set.get( - allocation_user__user=user_obj, - allocation_attribute_type__name='Cluster Account Status', - value__in=['Pending - Add', 'Processing', 'Active']) - - def get_project_compute_resource_name(project_obj): """Return the name of the '{cluster_name} Compute' Resource that corresponds to the given Project. diff --git a/coldfront/core/portal/templates/portal/authorized_home.html b/coldfront/core/portal/templates/portal/authorized_home.html index 1c3a5ea5c..22cd3de1c 100644 --- a/coldfront/core/portal/templates/portal/authorized_home.html +++ b/coldfront/core/portal/templates/portal/authorized_home.html @@ -160,17 +160,7 @@

My {{ PROGRAM_NAME_SHORT }} Cluster Projects »

{{ project.cluster_name|upper }} - {% if project.name in pending_removal_request_projects %} - Pending Removal - {% elif 'Active' in project.display_status %} - Active - {% elif 'Pending' in project.display_status %} - Pending - {% elif 'Processing' in project.display_status %} - Processing - {% else %} - No Access - {% endif %} + {% include "allocation/cluster_access_badge.html" with status=project.display_status %} {% endfor %} @@ -262,6 +252,7 @@

Allocations »

diff --git a/coldfront/core/portal/templates/portal/info_hover_popup.html b/coldfront/core/portal/templates/portal/info_hover_popup.html new file mode 100644 index 000000000..2d0b59516 --- /dev/null +++ b/coldfront/core/portal/templates/portal/info_hover_popup.html @@ -0,0 +1,20 @@ +{% comment %} + +Display an info icon that, when hovered over, displays a popup that has a title +and content (text). + +Usage: {% include "portal/info_hover_popup.html" with title="title" content="content" %} + +The following jQuery code must be included in the calling template for the popup +to appear: + +$(document).ready(function(){ + $('[data-toggle="popover"]').popover(); +}); + +{% endcomment %} + + + {{ title }} Info Hover Popup Text + + diff --git a/coldfront/core/portal/views.py b/coldfront/core/portal/views.py index 54591915a..397fae100 100644 --- a/coldfront/core/portal/views.py +++ b/coldfront/core/portal/views.py @@ -12,6 +12,7 @@ AllocationUser, AllocationUserAttribute) from coldfront.core.allocation.utils import get_project_compute_resource_name +from coldfront.core.allocation.utils import has_cluster_access # from coldfront.core.grant.models import Grant from coldfront.core.portal.utils import (generate_allocations_chart_data, generate_publication_by_year_chart_data, @@ -28,6 +29,27 @@ def home(request): + def _compute_project_user_cluster_access_statuses(_user): + """Return a dict mapping each Project object that the given User + is associated with to a str describing the user's access to the + cluster under the project.""" + statuses = {} + + cluster_access_attributes = AllocationUserAttribute.objects.filter( + allocation_attribute_type__name='Cluster Account Status', + allocation_user__user=_user) + for attribute in cluster_access_attributes: + _project = attribute.allocation.project + statuses[_project] = attribute.value + + for project_user_removal_request in \ + ProjectUserRemovalRequest.objects.filter( + project_user__user=_user, status__name='Pending'): + _project = project_user_removal_request.project_user.project + statuses[_project] = 'Pending - Remove' + + return statuses + context = {} if request.user.is_authenticated: template_name = 'portal/authorized_home.html' @@ -37,23 +59,17 @@ def home(request): Q(projectuser__status__name__in=['Active', 'Pending - Remove'])) ).distinct().order_by('name') - cluster_access_attributes = AllocationUserAttribute.objects.filter(allocation_attribute_type__name='Cluster Account Status', - allocation_user__user=request.user) - access_states = {} - for attribute in cluster_access_attributes: - project = attribute.allocation.project - status = attribute.value - access_states[project] = status + access_states = _compute_project_user_cluster_access_statuses( + request.user) for project in project_list: - project.display_status = access_states.get(project, None) - if (project.display_status is not None and - 'Active' in project.display_status): - context['cluster_username'] = request.user.username - + project.display_status = access_states.get(project, 'None') resource_name = get_project_compute_resource_name(project) project.cluster_name = resource_name.replace(' Compute', '') + if has_cluster_access(request.user): + context['cluster_username'] = request.user.username + allocation_list = Allocation.objects.filter( Q(status__name__in=['Active', 'New', 'Renewal Requested', ]) & Q(project__status__name__in=['Active', 'New']) & @@ -74,13 +90,6 @@ def home(request): context['num_join_requests'] = num_join_requests - context['pending_removal_request_projects'] = \ - [removal_request.project_user.project.name - for removal_request in - ProjectUserRemovalRequest.objects.filter( - Q(project_user__user__username=request.user.username) & - Q(status__name='Pending'))] - else: template_name = 'portal/nonauthorized_home.html' diff --git a/coldfront/core/project/templates/project/project_detail.html b/coldfront/core/project/templates/project/project_detail.html index 80f214a89..dd52087b1 100644 --- a/coldfront/core/project/templates/project/project_detail.html +++ b/coldfront/core/project/templates/project/project_detail.html @@ -290,14 +290,13 @@

Email Role - - Role Help Text - - + {% include "portal/info_hover_popup.html" with title="Role" content="Manager role grants user access to add/remove users, and allocations to the project." %} Cluster Username - Project Access on Cluster - + + Project Access on Cluster + {% include "portal/info_hover_popup.html" with title="Project Access on Cluster" content="This denotes whether the user's cluster account has been configured to have access to the project." %} + {% if is_allowed_to_update_project %} Actions {% endif %} @@ -319,31 +318,19 @@

{% endif %} - {% if user.cluster_access_status == "Active" %} - - Active - - {% elif user.cluster_access_status == "Pending - Add" %} - - Pending - - {% elif user.cluster_access_status == "Processing" %} - - Processing - - {% else %} - - No Access - - {% if cluster_accounts_requestable and is_allowed_to_update_project and user.user in project.pis or user.user in project.managers %} -

-
- {% csrf_token %} - -
+ {% include "allocation/cluster_access_badge.html" with status=user.cluster_access_status %} + {% if user.cluster_access_status == "None" %} + {% if user.role.name == "Principal Investigator" or user.role.name == "Manager" %} + {% if cluster_accounts_requestable and is_allowed_to_update_project %} +

+
+ {% csrf_token %} + +
+ {% endif %} {% endif %} {% endif %} diff --git a/coldfront/core/project/templates/project/project_user_detail.html b/coldfront/core/project/templates/project/project_user_detail.html index f67a0a7a1..a6f34e26f 100644 --- a/coldfront/core/project/templates/project/project_user_detail.html +++ b/coldfront/core/project/templates/project/project_user_detail.html @@ -102,34 +102,18 @@

Project: {{project_obj.name}}


Project Access on Cluster: - {% if cluster_access_status == 'Active' %} - - Active - - {% elif cluster_access_status == 'Pending - Add' %} - - Pending - - {% elif cluster_access_status == 'Processing' %} - - Processing - - {% elif cluster_access_status == 'None' %} - - No Access - - {% if project_user_obj.user in project_user_obj.project.pis or project_user_obj.user in project_user_obj.project.managers %} + {% include "allocation/cluster_access_badge.html" with status=cluster_access_status %} + {% if cluster_access_status == "None" %} + {% if project_user_obj.role.name == "Principal Investigator" or project_user_obj.role.name == "Manager" %}

{% csrf_token %}
{% endif %} - {% else %} - Failed to retrieve status. Please contact an administrator. {% endif %} @@ -139,4 +123,10 @@

Project: {{project_obj.name}}


+ + {% endblock%} diff --git a/coldfront/core/project/views.py b/coldfront/core/project/views.py index 17fdb7533..2bb3979fc 100644 --- a/coldfront/core/project/views.py +++ b/coldfront/core/project/views.py @@ -20,7 +20,6 @@ AllocationStatusChoice, AllocationUserAttribute, AllocationUserStatusChoice) -from coldfront.core.allocation.utils import get_allocation_user_cluster_access_status from coldfront.core.allocation.utils import get_project_compute_allocation from coldfront.core.allocation.utils import get_project_compute_resource_name # from coldfront.core.grant.models import Grant @@ -138,8 +137,7 @@ def get_context_data(self, **kwargs): allocation_obj.allocationuserattribute_set.select_related( 'allocation_user__user' ).filter( - allocation_attribute_type__name='Cluster Account Status', - value__in=['Pending - Add', 'Processing', 'Active']) + allocation_attribute_type__name='Cluster Account Status') for status in statuses: username = status.allocation_user.user.username cluster_access_statuses[username] = status.value @@ -1109,8 +1107,9 @@ def get(self, request, *args, **kwargs): else: try: cluster_access_status = \ - get_allocation_user_cluster_access_status( - allocation_obj, project_user_obj.user).value + allocation_obj.allocationuserattribute_set.get( + allocation_user__user=project_user_obj.user, + allocation_attribute_type__name='Cluster Account Status').value except AllocationUserAttribute.DoesNotExist: cluster_access_status = 'None' except AllocationUserAttribute.MultipleObjectsReturned: