From a168ae4665f75957210325d3de98e23e74ae4c21 Mon Sep 17 00:00:00 2001 From: GDay <1939656+GDay@users.noreply.github.com> Date: Fri, 29 Mar 2024 02:29:48 +0100 Subject: [PATCH 1/2] Allow manually adding hardware to user --- .../templates/_toggle_button_hardware.html | 9 +++ back/admin/people/templates/add_hardware.html | 38 +++++++++++++ .../people/templates/colleague_update.html | 5 ++ back/admin/people/tests.py | 55 +++++++++++++++++++ back/admin/people/urls.py | 10 ++++ back/admin/people/views.py | 33 +++++++++++ 6 files changed, 150 insertions(+) create mode 100644 back/admin/people/templates/_toggle_button_hardware.html create mode 100644 back/admin/people/templates/add_hardware.html diff --git a/back/admin/people/templates/_toggle_button_hardware.html b/back/admin/people/templates/_toggle_button_hardware.html new file mode 100644 index 000000000..4b3725b07 --- /dev/null +++ b/back/admin/people/templates/_toggle_button_hardware.html @@ -0,0 +1,9 @@ +{% load i18n %} +
+ + {% if template in object.hardware.all %} + {% translate "Added" %} + {% else %} + {% translate "Add" %} + {% endif %} +
diff --git a/back/admin/people/templates/add_hardware.html b/back/admin/people/templates/add_hardware.html new file mode 100644 index 000000000..5094a34cd --- /dev/null +++ b/back/admin/people/templates/add_hardware.html @@ -0,0 +1,38 @@ +{% extends 'admin_base.html' %} +{% load i18n %} + +{% block content %} +
+ +
+

{% translate "Changing hardware here will not send any messages to colleagues to send out or collect hardware. Use the sequences for that instead!"%}

+
+ +
+
+ + + + + + + + + + {% for template in object_list %} + + + + + + {% endfor %} + +
{% translate "Name" %}{% translate "Tags" %}
{{ template.name }}{% for tag in template.tags %}{{ tag }}{% endfor %} + {% include "_toggle_button_hardware.html" %} +
+ {% include "_paginator.html" %} +
+
+
+{% endblock %} diff --git a/back/admin/people/templates/colleague_update.html b/back/admin/people/templates/colleague_update.html index 34ac4828e..ce666372d 100644 --- a/back/admin/people/templates/colleague_update.html +++ b/back/admin/people/templates/colleague_update.html @@ -78,6 +78,11 @@

{% translate "Hardware" %}

{% endfor %} + diff --git a/back/admin/people/tests.py b/back/admin/people/tests.py index 34dd1d164..31258bdfd 100644 --- a/back/admin/people/tests.py +++ b/back/admin/people/tests.py @@ -2726,6 +2726,61 @@ def test_employee_toggle_resources( assert not employee1.resources.filter(id=resource1.id).exists() +@pytest.mark.django_db +def test_employee_hardware( + client, django_user_model, employee_factory, hardware_factory +): + client.force_login( + django_user_model.objects.create(role=get_user_model().Role.ADMIN) + ) + + employee1 = employee_factory() + hardware1 = hardware_factory() + hardware2 = hardware_factory(template=False) + + url = reverse("people:add_hardware", args=[employee1.id]) + response = client.get(url, follow=True) + + assert hardware1.name in response.content.decode() + # Only show templates + assert hardware2.name not in response.content.decode() + assert "Added" not in response.content.decode() + + # Add resource to user + employee1.hardware.add(hardware1) + + response = client.get(url, follow=True) + + # Has been added, so change button name + assert hardware2.name not in response.content.decode() + assert "Added" in response.content.decode() + + +@pytest.mark.django_db +def test_employee_toggle_hardware( + client, django_user_model, employee_factory, hardware_factory +): + client.force_login( + django_user_model.objects.create(role=get_user_model().Role.ADMIN) + ) + + hardware1 = hardware_factory() + employee1 = employee_factory() + + url = reverse("people:toggle_hardware", args=[employee1.id, hardware1.id]) + response = client.post(url, follow=True) + + assert "Added" in response.content.decode() + assert employee1.hardware.filter(id=hardware1.id).exists() + + # Now remove the item + response = client.post(url, follow=True) + + assert "Add" in response.content.decode() + assert not employee1.resources.filter(id=hardware1.id).exists() + + + @pytest.mark.django_db def test_visibility_import_employees_button( client, diff --git a/back/admin/people/urls.py b/back/admin/people/urls.py index db95391b2..830aba164 100644 --- a/back/admin/people/urls.py +++ b/back/admin/people/urls.py @@ -168,6 +168,16 @@ views.ColleagueResourceView.as_view(), name="add_resource", ), + path( + "colleagues//hardware/", + views.ColleagueHardwareView.as_view(), + name="add_hardware", + ), + path( + "colleagues//hardware//", + views.ColleagueToggleHardwareView.as_view(), + name="toggle_hardware", + ), path( "colleagues//resource//", views.ColleagueToggleResourceView.as_view(), diff --git a/back/admin/people/views.py b/back/admin/people/views.py index a5811bad5..5f9b362da 100644 --- a/back/admin/people/views.py +++ b/back/admin/people/views.py @@ -34,6 +34,7 @@ LoginRequiredMixin, ManagerPermMixin, ) +from admin.hardware.models import Hardware from users.models import ToDoUser from .forms import ( @@ -117,6 +118,38 @@ def get_context_data(self, **kwargs): return context +class ColleagueHardwareView(LoginRequiredMixin, ManagerPermMixin, DetailView): + template_name = "add_hardware.html" + model = get_user_model() + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + user = context["object"] + context["title"] = _("Add new hardware for %(name)s") % { + "name": user.full_name + } + context["subtitle"] = _("Employee") + context["object_list"] = Hardware.templates.all() + return context + + +class ColleagueToggleHardwareView(LoginRequiredMixin, ManagerPermMixin, View): + template_name = "_toggle_button_hardware.html" + + def post(self, request, pk, template_id, *args, **kwargs): + context = {} + user = get_object_or_404(get_user_model(), id=pk) + hardware = get_object_or_404(Hardware, id=template_id, template=True) + if user.hardware.filter(id=hardware.id).exists(): + user.hardware.remove(hardware) + else: + user.hardware.add(hardware) + context["id"] = id + context["template"] = hardware + context["object"] = user + return render(request, self.template_name, context) + + class ColleagueResourceView(LoginRequiredMixin, ManagerPermMixin, DetailView): template_name = "add_resources.html" model = get_user_model() From ed9f224c496dc4e728fd306177fa703b22c6e4f2 Mon Sep 17 00:00:00 2001 From: GDay <1939656+GDay@users.noreply.github.com> Date: Fri, 29 Mar 2024 02:38:48 +0100 Subject: [PATCH 2/2] ruff fixes --- back/admin/people/tests.py | 1 - back/admin/people/views.py | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/back/admin/people/tests.py b/back/admin/people/tests.py index 31258bdfd..b913e590b 100644 --- a/back/admin/people/tests.py +++ b/back/admin/people/tests.py @@ -2780,7 +2780,6 @@ def test_employee_toggle_hardware( assert not employee1.resources.filter(id=hardware1.id).exists() - @pytest.mark.django_db def test_visibility_import_employees_button( client, diff --git a/back/admin/people/views.py b/back/admin/people/views.py index 5f9b362da..90ad8feef 100644 --- a/back/admin/people/views.py +++ b/back/admin/people/views.py @@ -14,6 +14,7 @@ from rest_framework.authentication import SessionAuthentication from admin.admin_tasks.models import AdminTask +from admin.hardware.models import Hardware from admin.integrations.exceptions import ( DataIsNotJSONError, FailedPaginatedResponseError, @@ -34,7 +35,6 @@ LoginRequiredMixin, ManagerPermMixin, ) -from admin.hardware.models import Hardware from users.models import ToDoUser from .forms import ( @@ -125,9 +125,7 @@ class ColleagueHardwareView(LoginRequiredMixin, ManagerPermMixin, DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) user = context["object"] - context["title"] = _("Add new hardware for %(name)s") % { - "name": user.full_name - } + context["title"] = _("Add new hardware for %(name)s") % {"name": user.full_name} context["subtitle"] = _("Employee") context["object_list"] = Hardware.templates.all() return context