diff --git a/coldfront/core/resource/forms.py b/coldfront/core/resource/forms.py index 559c9e991..9a1a2268b 100644 --- a/coldfront/core/resource/forms.py +++ b/coldfront/core/resource/forms.py @@ -58,6 +58,11 @@ def __init__(self, *args, **kwargs): self.fields['resource_attribute_type'].queryset = self.fields['resource_attribute_type'].queryset.order_by(Lower('name')) +class ResourceAttributeUpdateForm(forms.Form): + resource_attribute_type_name = forms.CharField(max_length=250, required=False, disabled=True) + value = forms.CharField(max_length=350, required=True) + + class ResourceAllocationUpdateForm(forms.Form): allocation_pk = forms.IntegerField(required=False) project = forms.CharField(max_length=250, required=False, disabled=True) diff --git a/coldfront/core/resource/templates/resource_detail.html b/coldfront/core/resource/templates/resource_detail.html index 69d077b99..545df6c17 100644 --- a/coldfront/core/resource/templates/resource_detail.html +++ b/coldfront/core/resource/templates/resource_detail.html @@ -24,6 +24,11 @@

Resource Information

+ {% if request.user.is_superuser and not owner_set%} + + {% endif %} {% csrf_token %}
@@ -100,6 +105,9 @@

Resou Add Resource Attribute + + Edit Resource Attributes + Delete Resource Attributes diff --git a/coldfront/core/resource/templates/resource_resourceattribute_edit.html b/coldfront/core/resource/templates/resource_resourceattribute_edit.html new file mode 100644 index 000000000..96a761bab --- /dev/null +++ b/coldfront/core/resource/templates/resource_resourceattribute_edit.html @@ -0,0 +1,101 @@ +{% extends "common/base.html" %} +{% load crispy_forms_tags %} +{% load static %} +{% load django_tables2 %} +{% load mathfilters %} +{% load common_tags %} +{% load fasrc_tags %} + +{% block title %}Edit Resource Attributes for {% endblock %} + +{% block content %} +
+
+

Edit Resource Attributes for {{resource.name}} {{resource.resource_type.name}}

+
+
+ +
+
+
+
+
+ {{ formset.management_form }} + {% csrf_token %} +

+ + + + + + + + + {% for form in formset.forms %} + + + + + {% if form.errors %} +
{{ form.errors }}
+ {% endif %} + + {% endfor %} + + + + +
#AttributeValue
{{ forloop.counter }} {{form.resource_attribute_type_name.value}} {{form.value}}
+ + {% if request.user.is_superuser %} + + {% endif %} +
+
+ + + + + + + + + + +{% endblock %} + diff --git a/coldfront/core/resource/urls.py b/coldfront/core/resource/urls.py index afb501f81..1b0b4c68e 100644 --- a/coldfront/core/resource/urls.py +++ b/coldfront/core/resource/urls.py @@ -13,4 +13,6 @@ resource_views.ResourceAttributeDeleteView.as_view(), name='resource-attribute-delete'), path('/resourceallocations/edit', resource_views.ResourceAllocationsEditView.as_view(), name='resource-allocations-edit'), + path('/resourceattributes/edit', resource_views.ResourceAttributeEditView.as_view(), + name='resource-attributes-edit'), ] \ No newline at end of file diff --git a/coldfront/core/resource/views.py b/coldfront/core/resource/views.py index 17ed02ee0..6ade74f87 100644 --- a/coldfront/core/resource/views.py +++ b/coldfront/core/resource/views.py @@ -21,6 +21,7 @@ ResourceAttributeCreateForm, ResourceSearchForm, ResourceAttributeDeleteForm, + ResourceAttributeUpdateForm, ResourceAllocationUpdateForm, ) from coldfront.core.allocation.models import AllocationStatusChoice, AllocationAttributeType, AllocationAttribute @@ -161,6 +162,12 @@ def get_context_data(self, **kwargs): 'effectvusage' ) ) + if 'Compute Node' in resource_obj.resource_type.name: + owner_attribute_list = list(filter(lambda attribute: attribute.resource_attribute_type.name.lower() in ['owner'], attributes)) + owner_attribute_value = '' + if len(owner_attribute_list) == 1: + owner_attribute_value = owner_attribute_list[0].value + context['owner_set'] = bool(owner_attribute_value) elif resource_obj.resource_type.name == 'Storage': allocation_total = {'size': 0, 'usage':0} for allocation in allocations: @@ -169,7 +176,6 @@ def get_context_data(self, **kwargs): if allocation.usage: allocation_total['usage'] += allocation.usage context['allocation_total'] = allocation_total - context['allocations'] = allocations context['resource'] = resource_obj context['attributes'] = attributes @@ -217,6 +223,85 @@ def get_success_url(self): return reverse('resource-detail', kwargs={'pk': self.kwargs.get('pk')}) +class ResourceAttributeEditView(LoginRequiredMixin, UserPassesTestMixin, TemplateView): + template_name = 'resource_resourceattribute_edit.html' + + def test_func(self): + """UserPassesTestMixin Tests""" + if self.request.user.is_superuser: + return True + err = 'You do not have permission to edit resource attributes.' + messages.error(self.request, err) + return False + + def get_formset_initial_data(self, resource_attributes): + edit_attributes_formset_initial_data = [] + if resource_attributes: + for attribute in resource_attributes: + edit_attributes_formset_initial_data.append( + { + 'resource_attribute_type_name': attribute.resource_attribute_type.name, + 'value': attribute.value, + } + ) + return edit_attributes_formset_initial_data + + def get_context_data(self, resource_obj): + context = {} + resource_attributes = resource_obj.resourceattribute_set.all() + if resource_attributes: + ResourceAttributeUpdateFormSet = formset_factory( + ResourceAttributeUpdateForm, + max_num=len(resource_attributes), + extra=0 + ) + edit_attributes_formset_initial_data = self.get_formset_initial_data(resource_attributes) + formset = ResourceAttributeUpdateFormSet( + initial=edit_attributes_formset_initial_data, + prefix='attributesform' + ) + context['formset'] = formset + context['resource'] = resource_obj + return context + + def get(self, request, *args, **kwargs): + resource_obj = get_object_or_404(Resource, pk=self.kwargs.get('pk')) + context = self.get_context_data(resource_obj) + return render(request, self.template_name, context) + + def post(self, request, *args, **kwargs): + pk = self.kwargs.get('pk') + resource_obj = get_object_or_404(Resource, pk=pk) + resource_attributes = resource_obj.resourceattribute_set.all() + edit_attributes_formset_initial_data = self.get_formset_initial_data(resource_attributes) + logger.warning(f'initial_data {edit_attributes_formset_initial_data}') + + ResourceAttributeUpdateFormSet = formset_factory( + ResourceAttributeUpdateForm, + max_num=len(resource_attributes), + extra=0 + ) + formset = ResourceAttributeUpdateFormSet( + request.POST, + initial=edit_attributes_formset_initial_data, + prefix='attributesform' + ) + if formset.is_valid(): + for form in formset.forms: + attribute_name = form.cleaned_data.get('resource_attribute_type_name') + attribute_value = form.cleaned_data.get('value') + resource_attribute = [attribute for attribute in resource_attributes if attribute.resource_attribute_type.name == attribute_name][0] + resource_attribute.value = attribute_value + resource_attribute.save() + messages.success(request, 'Resource attributes update complete.') + return HttpResponseRedirect(reverse('resource-attributes-edit', kwargs={'pk': pk})) + else: + messages.error(request, 'Errors encountered, changes not saved. Check the form for details') + context = self.get_context_data(resource_obj) + context['formset'] = formset + return render(request, self.template_name, context) + + class ResourceAttributeDeleteView(LoginRequiredMixin, UserPassesTestMixin, TemplateView): template_name = 'resource_resourceattribute_delete.html'