From 0180e88663980ae012de82d4838a37b7293ecc46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nj=C3=A5l=20Telst=C3=B8?= Date: Wed, 4 Oct 2023 18:16:04 +0200 Subject: [PATCH 01/40] Listing group applications (WIP) --- .../internalportal/applications.html | 28 +++++++++++++++ internalportal/urls.py | 1 + internalportal/views.py | 36 +++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 internalportal/templates/internalportal/applications.html diff --git a/internalportal/templates/internalportal/applications.html b/internalportal/templates/internalportal/applications.html new file mode 100644 index 000000000..3e1c57b46 --- /dev/null +++ b/internalportal/templates/internalportal/applications.html @@ -0,0 +1,28 @@ +{% extends "website/base.html" %} +{% load static %} + +{% block content %} +
+
+
+
+

Søknader

+
+
+
+
+ +
+
+
+
+ {% for application in applications %} +
  • +

    {{ application.name }}

    +
  • + {% endfor %} +
    +
    +
    +
    +{% endblock %} diff --git a/internalportal/urls.py b/internalportal/urls.py index 1640ce79d..4b2eeb0de 100644 --- a/internalportal/urls.py +++ b/internalportal/urls.py @@ -6,4 +6,5 @@ urlpatterns = [ path("", views.InternalPortalView.as_view(), name="internalportal"), + path("applications/", views.ApplicationsView.as_view(), name="applications"), ] diff --git a/internalportal/views.py b/internalportal/views.py index cdabb0fde..82513ad4d 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -2,8 +2,16 @@ from django.contrib.auth import get_user_model from django.contrib.auth.mixins import PermissionRequiredMixin +from django.contrib.auth.mixins import ( + LoginRequiredMixin, + PermissionRequiredMixin, + UserPassesTestMixin, +) +from django.db.models import Q from django.views.generic import TemplateView +from applications.models import Application, ApplicationGroup +from committees.models import Committee from inventory.models.item_loan import ItemLoan from news.models import Article, Event @@ -39,3 +47,31 @@ def get_context_data(self, *args, **kwargs): ) return context + + +class ApplicationsView(LoginRequiredMixin, UserPassesTestMixin, TemplateView): + template_name = "internalportal/applications.html" + permission_required = "userprofile.is_active_member" + + def test_func(self): + return get_commitee_with_leader(self.request.user) is not None + + def get_context_data(self, *args, **kwargs): + context = super().get_context_data(*args, **kwargs) + commitee = get_commitee_with_leader(self.request.user) + + # FIXME: Why is a commitee not directly related to an application group? + application_group = ApplicationGroup.objects.filter(name=commitee.name).first() + + # TODO: Only get applications with group as first priority + group_choice_query = Application.objects.filter(group_choice__priority=1) + print(group_choice_query.count()) + context["applications"] = Application.objects.filter( + group_choice=application_group + ) + return context + + +def get_commitee_with_leader(user): + query = Q(main_lead=user.id) | Q(second_lead=user.id) + return Committee.objects.filter(query).first() From 9b36c59a3b360455eb64f6e11a716f374f178d6e Mon Sep 17 00:00:00 2001 From: zara <496122@student.fontys.nl> Date: Wed, 4 Oct 2023 19:59:04 +0200 Subject: [PATCH 02/40] Fixed displayed application names on internal portal --- internalportal/views.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/internalportal/views.py b/internalportal/views.py index 82513ad4d..11a217f87 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -63,12 +63,10 @@ def get_context_data(self, *args, **kwargs): # FIXME: Why is a commitee not directly related to an application group? application_group = ApplicationGroup.objects.filter(name=commitee.name).first() - # TODO: Only get applications with group as first priority - group_choice_query = Application.objects.filter(group_choice__priority=1) - print(group_choice_query.count()) - context["applications"] = Application.objects.filter( - group_choice=application_group + application_query = Q(applicationgroupchoice__priority=1) & Q( + applicationgroupchoice__group=application_group.id ) + context["applications"] = Application.objects.filter(application_query) return context From 566bf90385b299686683a839624b9a7f57b6509c Mon Sep 17 00:00:00 2001 From: zara <496122@student.fontys.nl> Date: Wed, 18 Oct 2023 20:16:59 +0200 Subject: [PATCH 03/40] Applicants' names are hyperlinks to individual applications --- .../templates/internalportal/application.html | 19 ++++++++++++++ .../internalportal/applications.html | 2 +- internalportal/urls.py | 1 + internalportal/views.py | 26 ++++++++++++++++--- 4 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 internalportal/templates/internalportal/application.html diff --git a/internalportal/templates/internalportal/application.html b/internalportal/templates/internalportal/application.html new file mode 100644 index 000000000..903c6b8b2 --- /dev/null +++ b/internalportal/templates/internalportal/application.html @@ -0,0 +1,19 @@ +{% extends "website/base.html" %} +{% load static %} + +{% block content %} +
    +

    {{ application.name }}

    +

    {{ application.email }}

    +

    {{ application.phone }}

    +

    {{ application.study }}

    +

    {{ application.year }}

    +

    {{ application.knowledge_of_hs }}

    +

    {{ application.about }}

    +

    {{ application.application_text }}

    +

    {{ application.group_choice }}

    +

    {{ application.project_interests }}

    +

    {{ application.application_date }}

    + +
    +{% endblock %} \ No newline at end of file diff --git a/internalportal/templates/internalportal/applications.html b/internalportal/templates/internalportal/applications.html index 3e1c57b46..e1d1108ea 100644 --- a/internalportal/templates/internalportal/applications.html +++ b/internalportal/templates/internalportal/applications.html @@ -18,7 +18,7 @@

    Søknader

    {% for application in applications %}
  • -

    {{ application.name }}

    +
    {{ application.name }}
  • {% endfor %}
    diff --git a/internalportal/urls.py b/internalportal/urls.py index 4b2eeb0de..f77b4130b 100644 --- a/internalportal/urls.py +++ b/internalportal/urls.py @@ -7,4 +7,5 @@ urlpatterns = [ path("", views.InternalPortalView.as_view(), name="internalportal"), path("applications/", views.ApplicationsView.as_view(), name="applications"), + path("applications/", views.ApplicationView.as_view(), name="application"), ] diff --git a/internalportal/views.py b/internalportal/views.py index 11a217f87..c2d786389 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -8,7 +8,7 @@ UserPassesTestMixin, ) from django.db.models import Q -from django.views.generic import TemplateView +from django.views.generic import DetailView, ListView, TemplateView from applications.models import Application, ApplicationGroup from committees.models import Committee @@ -49,14 +49,15 @@ def get_context_data(self, *args, **kwargs): return context -class ApplicationsView(LoginRequiredMixin, UserPassesTestMixin, TemplateView): +class ApplicationsView(ListView, LoginRequiredMixin, UserPassesTestMixin): template_name = "internalportal/applications.html" permission_required = "userprofile.is_active_member" + context_object_name = "applications" def test_func(self): return get_commitee_with_leader(self.request.user) is not None - def get_context_data(self, *args, **kwargs): + """def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) commitee = get_commitee_with_leader(self.request.user) @@ -67,7 +68,24 @@ def get_context_data(self, *args, **kwargs): applicationgroupchoice__group=application_group.id ) context["applications"] = Application.objects.filter(application_query) - return context + return context """ + + def get_queryset(self): + commitee = get_commitee_with_leader(self.request.user) + + # FIXME: Why is a commitee not directly related to an application group? + application_group = ApplicationGroup.objects.filter(name=commitee.name).first() + + application_query = Q(applicationgroupchoice__priority=1) & Q( + applicationgroupchoice__group=application_group.id + ) + return Application.objects.filter(application_query) + + +class ApplicationView(DetailView): + model = Application + template_name = "internalportal/application.html" + context_object_name = "application" def get_commitee_with_leader(user): From dd067c03200e104ab6c8d5c21d95f74d3d066d58 Mon Sep 17 00:00:00 2001 From: zara <496122@student.fontys.nl> Date: Wed, 18 Oct 2023 20:32:20 +0200 Subject: [PATCH 04/40] Finished basic application look --- .../templates/internalportal/application.html | 4 +++- internalportal/views.py | 13 ------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/internalportal/templates/internalportal/application.html b/internalportal/templates/internalportal/application.html index 903c6b8b2..1b414029d 100644 --- a/internalportal/templates/internalportal/application.html +++ b/internalportal/templates/internalportal/application.html @@ -11,7 +11,9 @@

    {{ application.knowledge_of_hs }}

    {{ application.about }}

    {{ application.application_text }}

    -

    {{ application.group_choice }}

    + {% for group in application.group_choice.all %} +

    {{ forloop.counter }}: {{ group.name }}

    + {% endfor %}

    {{ application.project_interests }}

    {{ application.application_date }}

    diff --git a/internalportal/views.py b/internalportal/views.py index c2d786389..2a574ee33 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -57,19 +57,6 @@ class ApplicationsView(ListView, LoginRequiredMixin, UserPassesTestMixin): def test_func(self): return get_commitee_with_leader(self.request.user) is not None - """def get_context_data(self, *args, **kwargs): - context = super().get_context_data(*args, **kwargs) - commitee = get_commitee_with_leader(self.request.user) - - # FIXME: Why is a commitee not directly related to an application group? - application_group = ApplicationGroup.objects.filter(name=commitee.name).first() - - application_query = Q(applicationgroupchoice__priority=1) & Q( - applicationgroupchoice__group=application_group.id - ) - context["applications"] = Application.objects.filter(application_query) - return context """ - def get_queryset(self): commitee = get_commitee_with_leader(self.request.user) From 60a1a0a5ce2f6b8a1a54ddc91e99387a0fd13f01 Mon Sep 17 00:00:00 2001 From: zara <496122@student.fontys.nl> Date: Wed, 1 Nov 2023 21:29:08 +0100 Subject: [PATCH 05/40] Admin of first choice group processes the application --- .../templates/internalportal/application.html | 5 ++- .../application_confirm_delete.html | 33 +++++++++++++++++++ internalportal/urls.py | 5 +++ internalportal/views.py | 20 ++++++++++- 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 internalportal/templates/internalportal/applications/application_confirm_delete.html diff --git a/internalportal/templates/internalportal/application.html b/internalportal/templates/internalportal/application.html index 1b414029d..0bea1db09 100644 --- a/internalportal/templates/internalportal/application.html +++ b/internalportal/templates/internalportal/application.html @@ -16,6 +16,9 @@ {% endfor %}

    {{ application.project_interests }}

    {{ application.application_date }}

    - + +
    + +
    {% endblock %} \ No newline at end of file diff --git a/internalportal/templates/internalportal/applications/application_confirm_delete.html b/internalportal/templates/internalportal/applications/application_confirm_delete.html new file mode 100644 index 000000000..6c7bbd8d5 --- /dev/null +++ b/internalportal/templates/internalportal/applications/application_confirm_delete.html @@ -0,0 +1,33 @@ +{% extends "website/base.html" %} +{% load i18n %} +{% load static %} +{% block content %} +
    +
    +
    +
    +
    +
    + {% csrf_token %} +

    {% trans "Confirm Action" %}

    +

    {% trans "Are you sure you want to delete the following application?" %}

    +
      +
    • Name: {{ application.name }}
    • +
    • {{ application.email }}
    • +
    • {{ application.phone }}
    • +
    • {{ application.study }}
    • +
    • {{ application.year }}
    • +
    • {{ application.knowledge_of_hs }}
    • +
    • {{ application.about }}
    • +
    • {{ application.application_text }}
    • +
    + +
    +

    + {% trans "NO, GO BACK" %} +
    +
    +
    +
    +
    +{% endblock content %} diff --git a/internalportal/urls.py b/internalportal/urls.py index f77b4130b..9c990b846 100644 --- a/internalportal/urls.py +++ b/internalportal/urls.py @@ -8,4 +8,9 @@ path("", views.InternalPortalView.as_view(), name="internalportal"), path("applications/", views.ApplicationsView.as_view(), name="applications"), path("applications/", views.ApplicationView.as_view(), name="application"), + path( + "applications/process/", + views.ApplicationProcessView.as_view(), + name="process_application", + ), ] diff --git a/internalportal/views.py b/internalportal/views.py index 2a574ee33..9931153cb 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -8,7 +8,7 @@ UserPassesTestMixin, ) from django.db.models import Q -from django.views.generic import DetailView, ListView, TemplateView +from django.views.generic import DeleteView, DetailView, ListView, TemplateView from applications.models import Application, ApplicationGroup from committees.models import Committee @@ -75,6 +75,24 @@ class ApplicationView(DetailView): context_object_name = "application" +class ApplicationProcessView(UserPassesTestMixin, DeleteView): + model = Application + template_name = "internalportal/applications/application_confirm_delete.html" + success_url = "/internalportal/applications/" + + def test_func(self): + commitee = get_commitee_with_leader(self.request.user) + if commitee is None: + return False + application = self.get_object() + return ( + application.group_choice.filter(applicationgroupchoice__priority=1) + .first() + .name + == commitee.name + ) + + def get_commitee_with_leader(user): query = Q(main_lead=user.id) | Q(second_lead=user.id) return Committee.objects.filter(query).first() From fb3e6c42143c2e2a9fb282dc3aadc78b7db9be90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nj=C3=A5l=20Telst=C3=B8?= Date: Wed, 8 Nov 2023 19:02:26 +0100 Subject: [PATCH 06/40] Fixed authentication error for applications page --- internalportal/views.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internalportal/views.py b/internalportal/views.py index 9931153cb..fdbdbbfde 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -8,6 +8,7 @@ UserPassesTestMixin, ) from django.db.models import Q +from django.shortcuts import redirect from django.views.generic import DeleteView, DetailView, ListView, TemplateView from applications.models import Application, ApplicationGroup @@ -49,7 +50,7 @@ def get_context_data(self, *args, **kwargs): return context -class ApplicationsView(ListView, LoginRequiredMixin, UserPassesTestMixin): +class ApplicationsView(LoginRequiredMixin, UserPassesTestMixin, ListView): template_name = "internalportal/applications.html" permission_required = "userprofile.is_active_member" context_object_name = "applications" @@ -57,6 +58,10 @@ class ApplicationsView(ListView, LoginRequiredMixin, UserPassesTestMixin): def test_func(self): return get_commitee_with_leader(self.request.user) is not None + def handle_no_permission(self): + # TODO: Display page asking user to log in if they are not + return redirect("/") + def get_queryset(self): commitee = get_commitee_with_leader(self.request.user) From 83a73e71bacb9a5f82f023829802362029ab96c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Wed, 8 Nov 2023 19:51:03 +0100 Subject: [PATCH 07/40] create view to move application to next group --- .../applications/next_group.html | 15 +++++++++ internalportal/views.py | 33 +++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 internalportal/templates/internalportal/applications/next_group.html diff --git a/internalportal/templates/internalportal/applications/next_group.html b/internalportal/templates/internalportal/applications/next_group.html new file mode 100644 index 000000000..1861aae2f --- /dev/null +++ b/internalportal/templates/internalportal/applications/next_group.html @@ -0,0 +1,15 @@ +{% extends "website/base.html" %} +{% load i18n %} +{% load static %} +{% block content %} + + +
    +
    {% trans "Send to the next group" %}
    +
    +
    +
    +
    +{% endblock content %} diff --git a/internalportal/views.py b/internalportal/views.py index fdbdbbfde..3cb78b63c 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -9,9 +9,15 @@ ) from django.db.models import Q from django.shortcuts import redirect -from django.views.generic import DeleteView, DetailView, ListView, TemplateView +from django.views.generic import ( + DeleteView, + DetailView, + ListView, + TemplateView, + UpdateView, +) -from applications.models import Application, ApplicationGroup +from applications.models import Application, ApplicationGroup, ApplicationGroupChoice from committees.models import Committee from inventory.models.item_loan import ItemLoan from news.models import Article, Event @@ -80,6 +86,25 @@ class ApplicationView(DetailView): context_object_name = "application" +class ApplicationNextGroupView(UpdateView, UserPassesTestMixin): + model = Application + template_name = "internalportal/applications/next_group.html" + success_url = "/internalportal/applications/" + + def test_func(self): + return get_commitee_with_leader(self.request.user) is not None + + # TODO: Connect application group with group directly + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + # current_chosen_group = ApplicationGroup.objects.filter() + context["next-group"] = ( + ApplicationGroupChoice.objects.filter(application=self.get_object()) + .order_by("priority") + .first() + ) + + class ApplicationProcessView(UserPassesTestMixin, DeleteView): model = Application template_name = "internalportal/applications/application_confirm_delete.html" @@ -98,6 +123,10 @@ def test_func(self): ) +def get_group_of_application(): + return None + + def get_commitee_with_leader(user): query = Q(main_lead=user.id) | Q(second_lead=user.id) return Committee.objects.filter(query).first() From 7dec059871e5dd5e4668e31e488f239ea3bedda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Wed, 8 Nov 2023 23:24:45 +0100 Subject: [PATCH 08/40] create application email text and upgrade views --- .../applications/new_application_email.txt | 22 +++++++++ internalportal/views.py | 49 ++++++++++++------- 2 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 applications/templates/applications/new_application_email.txt diff --git a/applications/templates/applications/new_application_email.txt b/applications/templates/applications/new_application_email.txt new file mode 100644 index 000000000..d4761432d --- /dev/null +++ b/applications/templates/applications/new_application_email.txt @@ -0,0 +1,22 @@ +Hei, + +Denne mailen blir sendt til deg fordi det har kommet en ny søknad til Hackerspace som har din gruppe på første valg. + +Du finner aktive søknader her: {{ applications_url }} + + +Mvh, +Hackerspace NTNU + +----------------------------------- + + +Hello, + +This email is sent to you because of a new applicant to Hackerspace with your group as highest priority. + +You can find active applications here: {{ application_url }} + + +Best regards, +Hackerspace NTNU diff --git a/internalportal/views.py b/internalportal/views.py index 3cb78b63c..c9fda827c 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -2,11 +2,14 @@ from django.contrib.auth import get_user_model from django.contrib.auth.mixins import PermissionRequiredMixin +from django.contrib import messages from django.contrib.auth.mixins import ( LoginRequiredMixin, PermissionRequiredMixin, UserPassesTestMixin, ) +from django.contrib.auth.models import Group +from django.contrib.auth.views import HttpResponseRedirect from django.db.models import Q from django.shortcuts import redirect from django.views.generic import ( @@ -14,8 +17,10 @@ DetailView, ListView, TemplateView, - UpdateView, + View, ) +from django.urls import reverse_lazy +from django.utils.translation import gettext_lazy as _ from applications.models import Application, ApplicationGroup, ApplicationGroupChoice from committees.models import Committee @@ -85,24 +90,33 @@ class ApplicationView(DetailView): template_name = "internalportal/application.html" context_object_name = "application" + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["next-group"] = ( + self.get_object().group_choice.order_by("priority").first() + ) + return context -class ApplicationNextGroupView(UpdateView, UserPassesTestMixin): - model = Application + +class ApplicationNextGroupView(View, UserPassesTestMixin): template_name = "internalportal/applications/next_group.html" success_url = "/internalportal/applications/" + success_message = _("Søknad sendt videre til neste gruppe") def test_func(self): return get_commitee_with_leader(self.request.user) is not None - # TODO: Connect application group with group directly - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - # current_chosen_group = ApplicationGroup.objects.filter() - context["next-group"] = ( - ApplicationGroupChoice.objects.filter(application=self.get_object()) - .order_by("priority") - .first() - ) + def get(self, request, *args, **kwargs): + application = Application.objects.filter(id=kwargs.get("pk")).first() + if not application: + messages.error(request, _("Søknaden finnes ikke")) + return HttpResponseRedirect(reverse_lazy("internalportal:applications")) + # send mail + + ApplicationGroupChoice.objects.filter(application=application).order_by( + "priority" + ).first().delete() + return HttpResponseRedirect(reverse_lazy("internalportal:applications")) class ApplicationProcessView(UserPassesTestMixin, DeleteView): @@ -116,15 +130,14 @@ def test_func(self): return False application = self.get_object() return ( - application.group_choice.filter(applicationgroupchoice__priority=1) - .first() - .name - == commitee.name + application.group_choice.order_by("priority").first().name == commitee.name ) -def get_group_of_application(): - return None +# TODO: Connect application group with group directly +def get_group_of_application(application): + application_group = application.group_choice.order_by("priority").first() + return Group.objects.filter(name=getattr(application_group, "name")).first() def get_commitee_with_leader(user): From adbf643580feee5a615042c03cad444aed9fe736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Thu, 9 Nov 2023 00:40:58 +0100 Subject: [PATCH 09/40] functionality to send email to person in group --- .../templates/internalportal/application.html | 9 ++- internalportal/urls.py | 5 ++ internalportal/views.py | 72 +++++++++++++------ 3 files changed, 62 insertions(+), 24 deletions(-) diff --git a/internalportal/templates/internalportal/application.html b/internalportal/templates/internalportal/application.html index 0bea1db09..6291cd76e 100644 --- a/internalportal/templates/internalportal/application.html +++ b/internalportal/templates/internalportal/application.html @@ -1,5 +1,6 @@ {% extends "website/base.html" %} {% load static %} +{% load i18n %} {% block content %}
    @@ -18,7 +19,9 @@

    {{ application.application_date }}

    - - + + {% if second_group %} + + {% endif %}
    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/internalportal/urls.py b/internalportal/urls.py index 9c990b846..042f4a05a 100644 --- a/internalportal/urls.py +++ b/internalportal/urls.py @@ -13,4 +13,9 @@ views.ApplicationProcessView.as_view(), name="process_application", ), + path( + "applications/next-group/", + views.ApplicationNextGroupView.as_view(), + name="next_group", + ), ] diff --git a/internalportal/views.py b/internalportal/views.py index c9fda827c..33323b732 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -8,9 +8,7 @@ PermissionRequiredMixin, UserPassesTestMixin, ) -from django.contrib.auth.models import Group from django.contrib.auth.views import HttpResponseRedirect -from django.db.models import Q from django.shortcuts import redirect from django.views.generic import ( DeleteView, @@ -20,6 +18,10 @@ View, ) from django.urls import reverse_lazy +from django.core.mail import send_mail +from django.db.models import OuterRef, Q, Subquery +from django.template.loader import render_to_string +from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ from applications.models import Application, ApplicationGroup, ApplicationGroupChoice @@ -74,15 +76,22 @@ def handle_no_permission(self): return redirect("/") def get_queryset(self): - commitee = get_commitee_with_leader(self.request.user) - - # FIXME: Why is a commitee not directly related to an application group? - application_group = ApplicationGroup.objects.filter(name=commitee.name).first() + committee = get_commitee_with_leader(self.request.user) + application_group = ApplicationGroup.objects.filter(name=committee.name).first() + + print(application_group, committee) + min_priority_subquery = ( + ApplicationGroupChoice.objects.filter( + group=OuterRef("applicationgroupchoice__group__id") + ) + .order_by("priority") + .values("priority")[:1] + ) - application_query = Q(applicationgroupchoice__priority=1) & Q( - applicationgroupchoice__group=application_group.id + return Application.objects.filter( + applicationgroupchoice__priority=Subquery(min_priority_subquery), + applicationgroupchoice__group=application_group, ) - return Application.objects.filter(application_query) class ApplicationView(DetailView): @@ -92,15 +101,16 @@ class ApplicationView(DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context["next-group"] = ( - self.get_object().group_choice.order_by("priority").first() - ) + groups = self.get_object().applicationgroupchoice_set.all().order_by("priority") + print(groups) + context["second_group"] = groups[1] if groups.count() > 1 else None return context class ApplicationNextGroupView(View, UserPassesTestMixin): - template_name = "internalportal/applications/next_group.html" - success_url = "/internalportal/applications/" + """Send an application to the next group""" + + success_url = reverse_lazy("internalportal:applications") success_message = _("Søknad sendt videre til neste gruppe") def test_func(self): @@ -111,7 +121,33 @@ def get(self, request, *args, **kwargs): if not application: messages.error(request, _("Søknaden finnes ikke")) return HttpResponseRedirect(reverse_lazy("internalportal:applications")) - # send mail + new_application_message = render_to_string( + "applications/new_application_email.txt", + {"applications_url": reverse("internalportal:applications")}, + ) + next_application_groups = application.applicationgroupchoice_set.order_by( + "priority" + ) + if next_application_groups.count() < 2: + messages.error(request, _("Søknaden har ingen flere grupper å gå til")) + return HttpResponseRedirect(reverse_lazy("internalportal:applications")) + next_group = next_application_groups[1] + committee = Committee.objects.filter(name=next_group.group.name).first() + emails = [ + getattr(committee.main_lead, "email", None), + getattr(committee.second_lead, "email", None), + ] + if not any(emails): + messages.error(request, _("Gruppen har ingen ledere")) + return + + send_mail( + _("Søknad sendt videre"), + new_application_message, + "Hackerspace NTNU", + emails, + fail_silently=False, + ) ApplicationGroupChoice.objects.filter(application=application).order_by( "priority" @@ -134,12 +170,6 @@ def test_func(self): ) -# TODO: Connect application group with group directly -def get_group_of_application(application): - application_group = application.group_choice.order_by("priority").first() - return Group.objects.filter(name=getattr(application_group, "name")).first() - - def get_commitee_with_leader(user): query = Q(main_lead=user.id) | Q(second_lead=user.id) return Committee.objects.filter(query).first() From 13c1bfedde03d7e0bdb0c6bdf0e0d5ff25335a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Mon, 13 Nov 2023 17:22:07 +0100 Subject: [PATCH 10/40] check if group exists before send mail --- internalportal/views.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/internalportal/views.py b/internalportal/views.py index 33323b732..8557f3117 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -69,7 +69,9 @@ class ApplicationsView(LoginRequiredMixin, UserPassesTestMixin, ListView): context_object_name = "applications" def test_func(self): - return get_commitee_with_leader(self.request.user) is not None + return get_commitee_with_leader(self.request.user) is not None or getattr( + self.request.user, "is_superuser", False + ) def handle_no_permission(self): # TODO: Display page asking user to log in if they are not @@ -79,7 +81,6 @@ def get_queryset(self): committee = get_commitee_with_leader(self.request.user) application_group = ApplicationGroup.objects.filter(name=committee.name).first() - print(application_group, committee) min_priority_subquery = ( ApplicationGroupChoice.objects.filter( group=OuterRef("applicationgroupchoice__group__id") @@ -102,7 +103,6 @@ class ApplicationView(DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) groups = self.get_object().applicationgroupchoice_set.all().order_by("priority") - print(groups) context["second_group"] = groups[1] if groups.count() > 1 else None return context @@ -114,7 +114,9 @@ class ApplicationNextGroupView(View, UserPassesTestMixin): success_message = _("Søknad sendt videre til neste gruppe") def test_func(self): - return get_commitee_with_leader(self.request.user) is not None + return get_commitee_with_leader(self.request.user) is not None or getattr( + self.request.user, "is_superuser", False + ) def get(self, request, *args, **kwargs): application = Application.objects.filter(id=kwargs.get("pk")).first() @@ -128,17 +130,32 @@ def get(self, request, *args, **kwargs): next_application_groups = application.applicationgroupchoice_set.order_by( "priority" ) + if next_application_groups.count() < 2: messages.error(request, _("Søknaden har ingen flere grupper å gå til")) return HttpResponseRedirect(reverse_lazy("internalportal:applications")) + next_group = next_application_groups[1] committee = Committee.objects.filter(name=next_group.group.name).first() + + if not committee: + messages.error( + request, + _("Gruppen {group_name} finnes ikke. Kontakt administrator.").format( + group_name=next_group.group.name + ), + ) + return HttpResponseRedirect(reverse_lazy("internalportal:applications")) + emails = [ getattr(committee.main_lead, "email", None), getattr(committee.second_lead, "email", None), ] if not any(emails): - messages.error(request, _("Gruppen har ingen ledere")) + messages.error( + request, + _("Gruppen {group} har ingen ledere").format(group=committee.name), + ) return send_mail( @@ -162,6 +179,8 @@ class ApplicationProcessView(UserPassesTestMixin, DeleteView): def test_func(self): commitee = get_commitee_with_leader(self.request.user) + if getattr(self.request.user, "is_superuser", False): + return True if commitee is None: return False application = self.get_object() From 0accdec9b27a2804866ec83d8b89eb4242a34935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Mon, 13 Nov 2023 23:23:27 +0100 Subject: [PATCH 11/40] check for superuser permissions --- internalportal/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internalportal/views.py b/internalportal/views.py index 8557f3117..09ca4b438 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -79,6 +79,8 @@ def handle_no_permission(self): def get_queryset(self): committee = get_commitee_with_leader(self.request.user) + if not committee: + return Application.objects.none() application_group = ApplicationGroup.objects.filter(name=committee.name).first() min_priority_subquery = ( @@ -88,6 +90,8 @@ def get_queryset(self): .order_by("priority") .values("priority")[:1] ) + if self.request.user.is_superuser: + return Application.objects.all() return Application.objects.filter( applicationgroupchoice__priority=Subquery(min_priority_subquery), From fe4a656b0985b3c7ef3db52912eca5da286fcbe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Wed, 15 Nov 2023 20:09:17 +0100 Subject: [PATCH 12/40] empty commit --- internalportal/views.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/internalportal/views.py b/internalportal/views.py index 09ca4b438..e0d4016c0 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -9,20 +9,13 @@ UserPassesTestMixin, ) from django.contrib.auth.views import HttpResponseRedirect -from django.shortcuts import redirect -from django.views.generic import ( - DeleteView, - DetailView, - ListView, - TemplateView, - View, -) -from django.urls import reverse_lazy from django.core.mail import send_mail from django.db.models import OuterRef, Q, Subquery +from django.shortcuts import redirect from django.template.loader import render_to_string from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ +from django.views.generic import DeleteView, DetailView, ListView, TemplateView, View from applications.models import Application, ApplicationGroup, ApplicationGroupChoice from committees.models import Committee From e3db43e041384a746b92ecd3241db7f0c0098095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Mon, 20 Nov 2023 20:03:26 +0100 Subject: [PATCH 13/40] delete unused file and remove superuser privelige --- applications/admin.py | 8 ++++++++ .../internalportal/applications/next_group.html | 15 --------------- internalportal/views.py | 12 ++---------- 3 files changed, 10 insertions(+), 25 deletions(-) delete mode 100644 internalportal/templates/internalportal/applications/next_group.html diff --git a/applications/admin.py b/applications/admin.py index aa9bd9b8b..9126b3ca3 100644 --- a/applications/admin.py +++ b/applications/admin.py @@ -22,3 +22,11 @@ class Media: @admin.register(Application) class ApplicationAdmin(BaseApplicationAdmin): inlines = [ApplicationGroupChoiceInline] + list_display = [ + "name", + "email", + "get_application_groups", + ] + + def get_application_groups(self, obj): + return ", ".join([group.name for group in obj.group_choice.all()]) diff --git a/internalportal/templates/internalportal/applications/next_group.html b/internalportal/templates/internalportal/applications/next_group.html deleted file mode 100644 index 1861aae2f..000000000 --- a/internalportal/templates/internalportal/applications/next_group.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "website/base.html" %} -{% load i18n %} -{% load static %} -{% block content %} - - -
    -
    {% trans "Send to the next group" %}
    -
    -
    -
    -
    -{% endblock content %} diff --git a/internalportal/views.py b/internalportal/views.py index e0d4016c0..f52e16f8a 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -62,9 +62,7 @@ class ApplicationsView(LoginRequiredMixin, UserPassesTestMixin, ListView): context_object_name = "applications" def test_func(self): - return get_commitee_with_leader(self.request.user) is not None or getattr( - self.request.user, "is_superuser", False - ) + return get_commitee_with_leader(self.request.user) is not None def handle_no_permission(self): # TODO: Display page asking user to log in if they are not @@ -83,8 +81,6 @@ def get_queryset(self): .order_by("priority") .values("priority")[:1] ) - if self.request.user.is_superuser: - return Application.objects.all() return Application.objects.filter( applicationgroupchoice__priority=Subquery(min_priority_subquery), @@ -111,9 +107,7 @@ class ApplicationNextGroupView(View, UserPassesTestMixin): success_message = _("Søknad sendt videre til neste gruppe") def test_func(self): - return get_commitee_with_leader(self.request.user) is not None or getattr( - self.request.user, "is_superuser", False - ) + return get_commitee_with_leader(self.request.user) is not None def get(self, request, *args, **kwargs): application = Application.objects.filter(id=kwargs.get("pk")).first() @@ -176,8 +170,6 @@ class ApplicationProcessView(UserPassesTestMixin, DeleteView): def test_func(self): commitee = get_commitee_with_leader(self.request.user) - if getattr(self.request.user, "is_superuser", False): - return True if commitee is None: return False application = self.get_object() From b3c0813c73d7ff6c4071ab4f25c65ec24a2fc3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Wed, 22 Nov 2023 19:46:56 +0100 Subject: [PATCH 14/40] create card for application --- .../internalportal/applications.html | 29 +++++++------------ .../applications/application_detail.html | 0 .../applications/application_list_card.html | 10 +++++++ website/templates/website/page_header.html | 9 ++++++ 4 files changed, 29 insertions(+), 19 deletions(-) create mode 100644 internalportal/templates/internalportal/applications/application_detail.html create mode 100644 internalportal/templates/internalportal/applications/application_list_card.html create mode 100644 website/templates/website/page_header.html diff --git a/internalportal/templates/internalportal/applications.html b/internalportal/templates/internalportal/applications.html index e1d1108ea..17cfb6cb3 100644 --- a/internalportal/templates/internalportal/applications.html +++ b/internalportal/templates/internalportal/applications.html @@ -2,27 +2,18 @@ {% load static %} {% block content %} -
    -
    -
    -
    -

    Søknader

    -
    -
    -
    -
    - + {% include "website/page_header.html" with title="Søknader" %}
    -
    -
    - {% for application in applications %} -
  • -
    {{ application.name }}
    -
  • - {% endfor %} -
    -
    +
    {% endblock %} diff --git a/internalportal/templates/internalportal/applications/application_detail.html b/internalportal/templates/internalportal/applications/application_detail.html new file mode 100644 index 000000000..e69de29bb diff --git a/internalportal/templates/internalportal/applications/application_list_card.html b/internalportal/templates/internalportal/applications/application_list_card.html new file mode 100644 index 000000000..078efa27f --- /dev/null +++ b/internalportal/templates/internalportal/applications/application_list_card.html @@ -0,0 +1,10 @@ +
    +
    +
    + {{ application.name }} + {{ application.email }} +

    {{ application.year }}. {{ application.study }}

    +

    {{ application.about }}

    +
    +
    +
    diff --git a/website/templates/website/page_header.html b/website/templates/website/page_header.html new file mode 100644 index 000000000..1da17f4da --- /dev/null +++ b/website/templates/website/page_header.html @@ -0,0 +1,9 @@ +
    +
    +
    +
    +

    {{ title }}

    +
    +
    +
    +
    From 030e683aa2f0a796d37bbd48a99fa37a749aec8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Thu, 23 Nov 2023 00:44:18 +0100 Subject: [PATCH 15/40] add approve application page and separate into components --- applications/models.py | 3 + authentication/views.py | 21 +++- fixtures.json | 2 +- .../templates/internalportal/application.html | 27 ----- .../applications/application.html | 21 ++++ .../application_confirm_delete.html | 29 ++--- .../applications/application_detail.html | 42 +++++++ .../{ => applications}/applications.html | 0 .../internalportal/applications/approve.html | 57 +++++++++ internalportal/urls.py | 11 +- internalportal/views.py | 108 ++++++++++++++---- 11 files changed, 254 insertions(+), 67 deletions(-) delete mode 100644 internalportal/templates/internalportal/application.html create mode 100644 internalportal/templates/internalportal/applications/application.html rename internalportal/templates/internalportal/{ => applications}/applications.html (100%) create mode 100644 internalportal/templates/internalportal/applications/approve.html diff --git a/applications/models.py b/applications/models.py index c32b27fb2..b3d1c97dd 100644 --- a/applications/models.py +++ b/applications/models.py @@ -94,3 +94,6 @@ class ApplicationGroupChoice(models.Model): application = models.ForeignKey(Application, on_delete=models.CASCADE) group = models.ForeignKey(ApplicationGroup, on_delete=models.CASCADE) priority = models.PositiveIntegerField(null=True) + + class Meta: + ordering = ["priority"] diff --git a/authentication/views.py b/authentication/views.py index e63ab0b2c..ea9c2be7b 100644 --- a/authentication/views.py +++ b/authentication/views.py @@ -1,4 +1,4 @@ -from django.contrib.auth import logout +from django.contrib.auth import get_user_model, logout from django.shortcuts import redirect from django.urls import reverse from django.views import View @@ -75,3 +75,22 @@ def associate_by_email(backend, details, user=None, *args, **kwargs): prison_user.save() return {"user": alt_users[0], "is_new": False} + + +def get_user_by_stud_or_ntnu_email(email: str): + """Check for the following cases: + + 1. Input email is the same as the user's email + 2. User has a stud.ntnu.no email and input email is ntnu.no + 3. User has a ntnu.no email and input email is stud.ntnu.no + """ + User = get_user_model() + + for query_email in [ + email, + email.split("@")[0] + "@stud.ntnu.no", + email.split("@")[0] + "@ntnu.no", + ]: + user = User.objects.filter(email=query_email).first() + if user: + return user diff --git a/fixtures.json b/fixtures.json index 7958d811a..2bb630853 100644 --- a/fixtures.json +++ b/fixtures.json @@ -635,7 +635,7 @@ "model": "applications.applicationgroup", "pk": 8, "fields": { - "name": "Spill", + "name": "Prosjekt: Spill", "text_main": "Det har i mange år vært interesse for å utvikle spill på Hackerspace og vi har i like mange år holdt på med en spillutviklingsgruppe for å tilfredsstille folket.\r\nDen aktive spillutviklingsgruppen ble ferdig med sitt nyeste prosjekt våren 2022 og skal fortsette morroa med mer spillutvikling.\r\nMålet for prosjektet er å produsere et spill som skal delta på Norwegian game awards. Så gled dere til de gøye, sprø og kaotiske eventyrene som dere vil ha i dette prosjektet!", "text_structure": "", "text_workload": "", diff --git a/internalportal/templates/internalportal/application.html b/internalportal/templates/internalportal/application.html deleted file mode 100644 index 6291cd76e..000000000 --- a/internalportal/templates/internalportal/application.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends "website/base.html" %} -{% load static %} -{% load i18n %} - -{% block content %} -
    -

    {{ application.name }}

    -

    {{ application.email }}

    -

    {{ application.phone }}

    -

    {{ application.study }}

    -

    {{ application.year }}

    -

    {{ application.knowledge_of_hs }}

    -

    {{ application.about }}

    -

    {{ application.application_text }}

    - {% for group in application.group_choice.all %} -

    {{ forloop.counter }}: {{ group.name }}

    - {% endfor %} -

    {{ application.project_interests }}

    -

    {{ application.application_date }}

    -
    -
    - - {% if second_group %} - - {% endif %} -
    -{% endblock %} diff --git a/internalportal/templates/internalportal/applications/application.html b/internalportal/templates/internalportal/applications/application.html new file mode 100644 index 000000000..239011f35 --- /dev/null +++ b/internalportal/templates/internalportal/applications/application.html @@ -0,0 +1,21 @@ +{% extends "website/base.html" %} +{% load static %} +{% load i18n %} + +{% block head %} + +{% endblock %} + +{% block content %} +
    + {% include "internalportal/applications/application_detail.html" with application=application %} + +
    +{% endblock %} diff --git a/internalportal/templates/internalportal/applications/application_confirm_delete.html b/internalportal/templates/internalportal/applications/application_confirm_delete.html index 6c7bbd8d5..6a03910c5 100644 --- a/internalportal/templates/internalportal/applications/application_confirm_delete.html +++ b/internalportal/templates/internalportal/applications/application_confirm_delete.html @@ -1,6 +1,11 @@ {% extends "website/base.html" %} {% load i18n %} {% load static %} + +{% block head %} + +{% endblock %} + {% block content %}
    @@ -9,22 +14,18 @@
    {% csrf_token %} -

    {% trans "Confirm Action" %}

    -

    {% trans "Are you sure you want to delete the following application?" %}

    -
      -
    • Name: {{ application.name }}
    • -
    • {{ application.email }}
    • -
    • {{ application.phone }}
    • -
    • {{ application.study }}
    • -
    • {{ application.year }}
    • -
    • {{ application.knowledge_of_hs }}
    • -
    • {{ application.about }}
    • -
    • {{ application.application_text }}
    • -
    - +
    + +

    {% trans "Bekreft handling" %}

    +

    {% trans "Er du sikker på at du vil slette søknaden? Den er ikke mulig å gjenopprette." %}

    + + {% include "internalportal/applications/application_detail.html" with application=application %} + +
    +


    - {% trans "NO, GO BACK" %} + {% trans "Nei, gå tilbake" %}
    diff --git a/internalportal/templates/internalportal/applications/application_detail.html b/internalportal/templates/internalportal/applications/application_detail.html index e69de29bb..026538133 100644 --- a/internalportal/templates/internalportal/applications/application_detail.html +++ b/internalportal/templates/internalportal/applications/application_detail.html @@ -0,0 +1,42 @@ +{% load i18n %} +
    +

    {{ application.name }}

    +
    +
    +
    {% trans "Personalia" %}
    +

    {% trans "Epost" %}: {{ application.email }}

    +

    {% trans "Tlf" %}: {{ application.phone }}

    +

    {% trans "Studie" %}: {{ application.study }}

    +

    {% trans "År" %}: {{ application.year }}

    +
    +
    + +
    +
    {% trans "Kunnskap om Hackerspace" %}
    +

    {{ application.knowledge_of_hs }}

    +
    + +
    +
    {% trans "Om meg" %}
    +

    {{ application.about }}

    +
    + +
    +
    {% trans "Søknadstekst" %}
    +

    {{ application.application_text }}

    +
    + +
    +
    {% trans "Grupper søkt" %}
    + {% for group in application.group_choice.all %} +

    {{ forloop.counter }}: {{ group.name }}

    + {% endfor %} +
    + +
    +
    {% trans "Andre interesser" %}
    +

    {{ application.project_interests }}

    +
    + +

    {% trans "Søknad motatt" %}: {{ application.application_date }}

    +
    diff --git a/internalportal/templates/internalportal/applications.html b/internalportal/templates/internalportal/applications/applications.html similarity index 100% rename from internalportal/templates/internalportal/applications.html rename to internalportal/templates/internalportal/applications/applications.html diff --git a/internalportal/templates/internalportal/applications/approve.html b/internalportal/templates/internalportal/applications/approve.html new file mode 100644 index 000000000..c3b0d089b --- /dev/null +++ b/internalportal/templates/internalportal/applications/approve.html @@ -0,0 +1,57 @@ +{% extends "website/base.html" %} +{% load static %} +{% load i18n %} + +{% block head %} + +{% endblock %} + +{% block content %} +
    +
    +
    + {% csrf_token %} +
    +
    + {% trans "Godkjenn søknad" %} + +
    +
    + {% trans "Navn" %}: {{ application.name }} +
    +
    + {% trans "Gruppe" %}: {{ group.name }} +
    +
    + +
    +
    +

    {% trans "For å kunne koble et nytt medlem må søkerens ntnu e-post benyttes." %}

    +

    {% trans "Be personen logge inn på nettsiden før godkjenning." %}

    +

    {% trans "Legg personen i riktige kommunikasjonskanaler og google drive" %}

    +
    +
    + +
    +
    + + +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    +
    +{% endblock %} diff --git a/internalportal/urls.py b/internalportal/urls.py index 042f4a05a..86788b580 100644 --- a/internalportal/urls.py +++ b/internalportal/urls.py @@ -9,13 +9,18 @@ path("applications/", views.ApplicationsView.as_view(), name="applications"), path("applications/", views.ApplicationView.as_view(), name="application"), path( - "applications/process/", - views.ApplicationProcessView.as_view(), - name="process_application", + "applications/delete/", + views.ApplicationRemoveView.as_view(), + name="delete_application", ), path( "applications/next-group/", views.ApplicationNextGroupView.as_view(), name="next_group", ), + path( + "applications/approve/", + views.ApplicationApproveView.as_view(), + name="approve_application", + ), ] diff --git a/internalportal/views.py b/internalportal/views.py index f52e16f8a..d444031bb 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -8,16 +8,19 @@ PermissionRequiredMixin, UserPassesTestMixin, ) +from django.contrib.auth.models import Group from django.contrib.auth.views import HttpResponseRedirect from django.core.mail import send_mail from django.db.models import OuterRef, Q, Subquery -from django.shortcuts import redirect +from django.shortcuts import get_object_or_404, redirect from django.template.loader import render_to_string from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ -from django.views.generic import DeleteView, DetailView, ListView, TemplateView, View +from django.views.generic import DeleteView, DetailView, ListView, TemplateView +from django.views.generic.edit import BaseDetailView from applications.models import Application, ApplicationGroup, ApplicationGroupChoice +from authentication.views import get_user_by_stud_or_ntnu_email from committees.models import Committee from inventory.models.item_loan import ItemLoan from news.models import Article, Event @@ -57,7 +60,7 @@ def get_context_data(self, *args, **kwargs): class ApplicationsView(LoginRequiredMixin, UserPassesTestMixin, ListView): - template_name = "internalportal/applications.html" + template_name = "internalportal/applications/applications.html" permission_required = "userprofile.is_active_member" context_object_name = "applications" @@ -74,25 +77,28 @@ def get_queryset(self): return Application.objects.none() application_group = ApplicationGroup.objects.filter(name=committee.name).first() - min_priority_subquery = ( - ApplicationGroupChoice.objects.filter( - group=OuterRef("applicationgroupchoice__group__id") - ) + first_group = ( + ApplicationGroupChoice.objects.filter(application=OuterRef("id")) .order_by("priority") - .values("priority")[:1] + .values("group")[:1] ) - return Application.objects.filter( - applicationgroupchoice__priority=Subquery(min_priority_subquery), - applicationgroupchoice__group=application_group, + return ( + Application.objects.filter(applicationgroupchoice__group=application_group) + .annotate(first_group=Subquery(first_group)) + .filter(first_group=application_group) ) -class ApplicationView(DetailView): +class ApplicationView(UserPassesTestMixin, DetailView): model = Application - template_name = "internalportal/application.html" + template_name = "internalportal/applications/application.html" context_object_name = "application" + def test_func(self): + committee = get_commitee_with_leader(self.request.user) + return first_application_group_is_committee(self.get_object(), committee) + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) groups = self.get_object().applicationgroupchoice_set.all().order_by("priority") @@ -100,14 +106,16 @@ def get_context_data(self, **kwargs): return context -class ApplicationNextGroupView(View, UserPassesTestMixin): +class ApplicationNextGroupView(UserPassesTestMixin, BaseDetailView): """Send an application to the next group""" + model = Application success_url = reverse_lazy("internalportal:applications") success_message = _("Søknad sendt videre til neste gruppe") def test_func(self): - return get_commitee_with_leader(self.request.user) is not None + committee = get_commitee_with_leader(self.request.user) + return first_application_group_is_committee(self.get_object(), committee) def get(self, request, *args, **kwargs): application = Application.objects.filter(id=kwargs.get("pk")).first() @@ -163,21 +171,79 @@ def get(self, request, *args, **kwargs): return HttpResponseRedirect(reverse_lazy("internalportal:applications")) -class ApplicationProcessView(UserPassesTestMixin, DeleteView): +class ApplicationRemoveView(UserPassesTestMixin, DeleteView): model = Application template_name = "internalportal/applications/application_confirm_delete.html" success_url = "/internalportal/applications/" def test_func(self): - commitee = get_commitee_with_leader(self.request.user) - if commitee is None: - return False + committee = get_commitee_with_leader(self.request.user) + return first_application_group_is_committee(self.get_object(), committee) + + +class ApplicationApproveView(ApplicationRemoveView): + template_name = "internalportal/applications/approve.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["group"] = ( + self.get_object() + .applicationgroupchoice_set.order_by("priority") + .first() + .group + ) + return context + + def delete(self, request, *args, **kwargs): + + # get email from request application = self.get_object() - return ( - application.group_choice.order_by("priority").first().name == commitee.name + + email = request.POST.get("email") + if not email: + email = application.email + + group_name = ( + application.applicationgroupchoice_set.order_by("priority") + .first() + .group.name ) + group = get_object_or_404(Group, name=group_name) + + # Force users to use their stud email in their application + user = get_user_by_stud_or_ntnu_email(email) + if not user: + messages.error( + request, + _( + "Få brukeren til å logge inn med Feide først " + "og bruk søkerens ntnu-mail." + ), + ) + return HttpResponseRedirect( + reverse_lazy( + "internalportal:application", kwargs={"pk": application.id} + ) + ) + + user.groups.add(group) + user.groups.add(get_object_or_404(Group, name="Medlem")) + user.save() + + # Send mail til søker + + return super().delete(request, *args, **kwargs) def get_commitee_with_leader(user): query = Q(main_lead=user.id) | Q(second_lead=user.id) return Committee.objects.filter(query).first() + + +def first_application_group_is_committee(application, committee): + if application is None or committee is None: + return False + return ( + application.applicationgroupchoice_set.order_by("priority").first().group.name + == committee.name + ) From 27c41d899eb801ae2b0944114d852a4c2e5659c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Thu, 23 Nov 2023 00:59:08 +0100 Subject: [PATCH 16/40] add link to applications --- .../templates/internalportal/internalportal.html | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/internalportal/templates/internalportal/internalportal.html b/internalportal/templates/internalportal/internalportal.html index 83fc32c06..081e3bf1d 100644 --- a/internalportal/templates/internalportal/internalportal.html +++ b/internalportal/templates/internalportal/internalportal.html @@ -168,6 +168,15 @@
    {% trans "Medlemsliste for dørtilgang" %}
    {% include "internalportal/door-access-member-list.html" with users=door_access_member_list next_year=next_year only %} {% endif %} + + From 89dfe528aed7a2094c2b04e4e6157d82bacf2378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Thu, 23 Nov 2023 01:07:05 +0100 Subject: [PATCH 17/40] add comments for future work --- .../templates/internalportal/applications/application.html | 1 + internalportal/views.py | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/internalportal/templates/internalportal/applications/application.html b/internalportal/templates/internalportal/applications/application.html index 239011f35..899f43019 100644 --- a/internalportal/templates/internalportal/applications/application.html +++ b/internalportal/templates/internalportal/applications/application.html @@ -9,6 +9,7 @@ {% block content %}
    {% include "internalportal/applications/application_detail.html" with application=application %} + {# Mulighet for å plotte inn informasjon om intervjutider, se over og sende det videre #}
    diff --git a/internalportal/views.py b/internalportal/views.py index d444031bb..80ca8b826 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -1,8 +1,7 @@ from datetime import datetime, timedelta -from django.contrib.auth import get_user_model -from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib import messages +from django.contrib.auth import get_user_model from django.contrib.auth.mixins import ( LoginRequiredMixin, PermissionRequiredMixin, @@ -196,7 +195,6 @@ def get_context_data(self, **kwargs): def delete(self, request, *args, **kwargs): - # get email from request application = self.get_object() email = request.POST.get("email") @@ -210,7 +208,6 @@ def delete(self, request, *args, **kwargs): ) group = get_object_or_404(Group, name=group_name) - # Force users to use their stud email in their application user = get_user_by_stud_or_ntnu_email(email) if not user: messages.error( From a7e6631c2fa14afdd20e15315f457085460a7cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Thu, 23 Nov 2023 11:31:50 +0100 Subject: [PATCH 18/40] separate into own personalia box --- .../applications/application_confirm_delete.html | 2 +- .../applications/application_detail.html | 10 +--------- .../internalportal/applications/applications.html | 2 +- .../internalportal/applications/personalia_box.html | 12 ++++++++++++ 4 files changed, 15 insertions(+), 11 deletions(-) create mode 100644 internalportal/templates/internalportal/applications/personalia_box.html diff --git a/internalportal/templates/internalportal/applications/application_confirm_delete.html b/internalportal/templates/internalportal/applications/application_confirm_delete.html index 6a03910c5..945b04f35 100644 --- a/internalportal/templates/internalportal/applications/application_confirm_delete.html +++ b/internalportal/templates/internalportal/applications/application_confirm_delete.html @@ -19,7 +19,7 @@

    {% trans "Bekreft handling" %}

    {% trans "Er du sikker på at du vil slette søknaden? Den er ikke mulig å gjenopprette." %}

    - {% include "internalportal/applications/application_detail.html" with application=application %} + {% include "internalportal/applications/personalia_box.html" with application=application %}
    diff --git a/internalportal/templates/internalportal/applications/application_detail.html b/internalportal/templates/internalportal/applications/application_detail.html index 026538133..451bf180a 100644 --- a/internalportal/templates/internalportal/applications/application_detail.html +++ b/internalportal/templates/internalportal/applications/application_detail.html @@ -1,15 +1,7 @@ {% load i18n %}

    {{ application.name }}

    -
    -
    -
    {% trans "Personalia" %}
    -

    {% trans "Epost" %}: {{ application.email }}

    -

    {% trans "Tlf" %}: {{ application.phone }}

    -

    {% trans "Studie" %}: {{ application.study }}

    -

    {% trans "År" %}: {{ application.year }}

    -
    -
    + {% include "internalportal/applications/personalia_box.html" with application=application %}
    {% trans "Kunnskap om Hackerspace" %}
    diff --git a/internalportal/templates/internalportal/applications/applications.html b/internalportal/templates/internalportal/applications/applications.html index 17cfb6cb3..d5bbbb3df 100644 --- a/internalportal/templates/internalportal/applications/applications.html +++ b/internalportal/templates/internalportal/applications/applications.html @@ -2,7 +2,7 @@ {% load static %} {% block content %} - {% include "website/page_header.html" with title="Søknader" %} + {% include "website/page_header.html" with title="{% trans 'Søknader' %}" %}
      diff --git a/internalportal/templates/internalportal/applications/personalia_box.html b/internalportal/templates/internalportal/applications/personalia_box.html new file mode 100644 index 000000000..e5678a3fb --- /dev/null +++ b/internalportal/templates/internalportal/applications/personalia_box.html @@ -0,0 +1,12 @@ +{% load i18n %} + +
      +
      +
      {% trans "Personalia" %}
      +

      {% trans "Navn" %}: {{ application.name }}

      +

      {% trans "Epost" %}: {{ application.email }}

      +

      {% trans "Tlf" %}: {{ application.phone }}

      +

      {% trans "Studie" %}: {{ application.study }}

      +

      {% trans "År" %}: {{ application.year }}

      +
      +
      From 221f57952e45c00579144f2cda6a323641b26f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Thu, 23 Nov 2023 13:42:06 +0100 Subject: [PATCH 19/40] send email on successful new application --- applications/admin.py | 9 ++++++- applications/forms.py | 24 ++++++++++++++++++- .../applications/application.html | 13 +++++++++- .../applications/applications.html | 4 +++- .../applications/send_email.html | 0 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 internalportal/templates/internalportal/applications/send_email.html diff --git a/applications/admin.py b/applications/admin.py index 9126b3ca3..08b8a00ad 100644 --- a/applications/admin.py +++ b/applications/admin.py @@ -29,4 +29,11 @@ class ApplicationAdmin(BaseApplicationAdmin): ] def get_application_groups(self, obj): - return ", ".join([group.name for group in obj.group_choice.all()]) + return ", ".join( + [ + group.name + for group in obj.group_choice.order_by( + "applicationgroupchoice__priority" + ) + ] + ) diff --git a/applications/forms.py b/applications/forms.py index 8f83e1ed0..037165159 100644 --- a/applications/forms.py +++ b/applications/forms.py @@ -1,6 +1,9 @@ from django.core.mail import send_mail from django.forms import ModelForm, Textarea, TextInput from django.template.loader import render_to_string +from django.urls import reverse + +from committees.models import Committee from .models import Application, ApplicationGroupChoice @@ -74,4 +77,23 @@ def send_email(self): [self.cleaned_data["email"]], fail_silently=False, ) - pass + + new_application_message = render_to_string( + "applications/new_application_email.txt", + {"applications_url": reverse("internalportal:applications")}, + ) + committee = Committee.objects.filter( + name=self.cleaned_data["group_choice"][0].name + ).first() + if committee: + emails = [ + getattr(committee.main_lead, "email", None), + getattr(committee.second_lead, "email", None), + ] + send_mail( + "[Hackerspace NTNU] Ny søknad!", + new_application_message, + "Hackerspace NTNU", + emails, + fail_silently=False, + ) diff --git a/internalportal/templates/internalportal/applications/application.html b/internalportal/templates/internalportal/applications/application.html index 899f43019..e0a20fec8 100644 --- a/internalportal/templates/internalportal/applications/application.html +++ b/internalportal/templates/internalportal/applications/application.html @@ -8,7 +8,18 @@ {% block content %}
      - {% include "internalportal/applications/application_detail.html" with application=application %} +
      +
      + {% include "internalportal/applications/personalia_box.html" with application=application %} +
      +
      +
      +
      +

      {% trans "Planlegg intervju" %}

      +
      +
      +
      +
      {# Mulighet for å plotte inn informasjon om intervjutider, se over og sende det videre #}
      diff --git a/internalportal/templates/internalportal/applications/applications.html b/internalportal/templates/internalportal/applications/applications.html index d5bbbb3df..b1a3d496c 100644 --- a/internalportal/templates/internalportal/applications/applications.html +++ b/internalportal/templates/internalportal/applications/applications.html @@ -1,8 +1,10 @@ {% extends "website/base.html" %} {% load static %} +{% load i18n %} {% block content %} - {% include "website/page_header.html" with title="{% trans 'Søknader' %}" %} + {% trans "Søknader" as applications_header %} + {% include "website/page_header.html" with title=applications_header %}
        diff --git a/internalportal/templates/internalportal/applications/send_email.html b/internalportal/templates/internalportal/applications/send_email.html new file mode 100644 index 000000000..e69de29bb From 768810a611acc30efae79c5e2a1f415aa61f94c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Sun, 26 Nov 2023 18:36:56 +0100 Subject: [PATCH 20/40] create form to send email to applicant --- internalportal/forms.py | 23 ++++++++++++++ .../{application_detail.html => answers.html} | 3 -- .../applications/application.html | 30 +++++++++++++++++-- .../applications/interview_email.txt | 13 ++++++++ .../applications/interview_email_form.html | 27 +++++++++++++++++ .../applications/personalia_box.html | 1 + .../applications/send_email.html | 0 internalportal/urls.py | 7 ++++- internalportal/views.py | 29 +++++++++++++++++- 9 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 internalportal/forms.py rename internalportal/templates/internalportal/applications/{application_detail.html => answers.html} (78%) create mode 100644 internalportal/templates/internalportal/applications/interview_email.txt create mode 100644 internalportal/templates/internalportal/applications/interview_email_form.html delete mode 100644 internalportal/templates/internalportal/applications/send_email.html diff --git a/internalportal/forms.py b/internalportal/forms.py new file mode 100644 index 000000000..f5ba72d9b --- /dev/null +++ b/internalportal/forms.py @@ -0,0 +1,23 @@ +from django.db.models.fields import forms +from django.utils.translation import gettext_lazy as _ + + +class InterviewEmailForm(forms.Form): + location = forms.CharField( + label=_("Plassering"), + max_length=100, + required=True, + ) + location_link = forms.CharField( + label=_("Lenke til plassering"), + max_length=100, + required=False, + ) + start_time = forms.DateTimeField( + label=_("Tidspunkt"), + required=True, + ) + end_time = forms.DateTimeField( + label=_("Sluttidspunkt"), + required=False, + ) diff --git a/internalportal/templates/internalportal/applications/application_detail.html b/internalportal/templates/internalportal/applications/answers.html similarity index 78% rename from internalportal/templates/internalportal/applications/application_detail.html rename to internalportal/templates/internalportal/applications/answers.html index 451bf180a..1aeef33e0 100644 --- a/internalportal/templates/internalportal/applications/application_detail.html +++ b/internalportal/templates/internalportal/applications/answers.html @@ -1,7 +1,5 @@ {% load i18n %}
        -

        {{ application.name }}

        - {% include "internalportal/applications/personalia_box.html" with application=application %}
        {% trans "Kunnskap om Hackerspace" %}
        @@ -30,5 +28,4 @@
        {% trans "Andre interesser" %}

        {{ application.project_interests }}

        -

        {% trans "Søknad motatt" %}: {{ application.application_date }}

        diff --git a/internalportal/templates/internalportal/applications/application.html b/internalportal/templates/internalportal/applications/application.html index e0a20fec8..c10871add 100644 --- a/internalportal/templates/internalportal/applications/application.html +++ b/internalportal/templates/internalportal/applications/application.html @@ -7,20 +7,41 @@ {% endblock %} {% block content %} + {% include "website/page_header.html" with title=application.name %}
        {% include "internalportal/applications/personalia_box.html" with application=application %} +
          +
        • + {% trans "Søknadssvar" %} +
          +
          + {% include "internalportal/applications/answers.html" with application=application %} +
          +
          +
        • +
        -

        {% trans "Planlegg intervju" %}

        +

        {% trans "Intervjuprosessen" %}

        +
          +
        1. {% trans "Les over søknaden" %}
        2. +
        3. {% trans "Send mail om tidspunkt og sted for foreslått intervju" %}
        4. +
        5. {% trans "Hold intervju" %}
        6. +
        7. {% trans "Få kandidaten til å logge inn på nettsiden" %}
        8. +
        9. {% trans "Godkjenn kandidaten og send mail at de har kommet inn med HowToHack dokumentet på Drive" %}
        10. +
        11. {% trans "Legg kandidaten inn i kommunikasjonskanaler" %}
        12. +
        +
        - {# Mulighet for å plotte inn informasjon om intervjutider, se over og sende det videre #}
        @@ -30,4 +51,9 @@

        {% trans "Planlegg intervju" %}

        {% endif %}
        + + {% endblock %} diff --git a/internalportal/templates/internalportal/applications/interview_email.txt b/internalportal/templates/internalportal/applications/interview_email.txt new file mode 100644 index 000000000..ab381e8de --- /dev/null +++ b/internalportal/templates/internalportal/applications/interview_email.txt @@ -0,0 +1,13 @@ +Hei {{ application.name }}, +Tusen takk for din søknad hos Hackerspace NTNU! + + +I forbindelse med opptaket hos Hackerspace NTNU, ønsker vi å kalle deg inn til et intervju. Intervjuet er en mulighet for oss til å bli enda bedre kjent med deg før det gjøres sluttvurderinger i opptaket, og en mulighet for deg til å stille spørsmål rundt opptaket, organisasjonen og annet dersom ønskelig. + +Foreslått tidspunkt for intervjuet er {{ interview.start_time }} i {{ interview.location }}. + +Vi ønsker gjerne at du bekrefter at tidspunktet passer, eller eventuelt svarer på mailen med timeplan / tidspunkter som passer bedre. + +Med vennlig hilsen, +{{ application_group }} +Hackerspace NTNU diff --git a/internalportal/templates/internalportal/applications/interview_email_form.html b/internalportal/templates/internalportal/applications/interview_email_form.html new file mode 100644 index 000000000..eac10ec4e --- /dev/null +++ b/internalportal/templates/internalportal/applications/interview_email_form.html @@ -0,0 +1,27 @@ +{% extends "website/base.html" %} +{% load static %} +{% load i18n %} + +{% block head %} + +{% endblock %} + +{% block content %} +
        +
        + {% csrf_token %} + {{ form.as_p }} + +
        + + {% if request.session.interview_email %} +
        +
        + {{ requeset.session.interview_email }} +
        +
        + {% endif %} +
        + + +{% endblock %} diff --git a/internalportal/templates/internalportal/applications/personalia_box.html b/internalportal/templates/internalportal/applications/personalia_box.html index e5678a3fb..a621ddd27 100644 --- a/internalportal/templates/internalportal/applications/personalia_box.html +++ b/internalportal/templates/internalportal/applications/personalia_box.html @@ -8,5 +8,6 @@
        {% trans "Personalia" %}

        {% trans "Tlf" %}: {{ application.phone }}

        {% trans "Studie" %}: {{ application.study }}

        {% trans "År" %}: {{ application.year }}

        +

        {% trans "Søknad motatt" %}: {{ application.application_date }}

      diff --git a/internalportal/templates/internalportal/applications/send_email.html b/internalportal/templates/internalportal/applications/send_email.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/internalportal/urls.py b/internalportal/urls.py index 86788b580..ba45c5638 100644 --- a/internalportal/urls.py +++ b/internalportal/urls.py @@ -19,8 +19,13 @@ name="next_group", ), path( - "applications/approve/", + "applications//approve", views.ApplicationApproveView.as_view(), name="approve_application", ), + path( + "applications//interview-email", + views.ApplicationInterviewEmailView.as_view(), + name="interview_email", + ), ] diff --git a/internalportal/views.py b/internalportal/views.py index 80ca8b826..14b4bb381 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -8,7 +8,7 @@ UserPassesTestMixin, ) from django.contrib.auth.models import Group -from django.contrib.auth.views import HttpResponseRedirect +from django.contrib.auth.views import FormView, HttpResponseRedirect from django.core.mail import send_mail from django.db.models import OuterRef, Q, Subquery from django.shortcuts import get_object_or_404, redirect @@ -21,6 +21,7 @@ from applications.models import Application, ApplicationGroup, ApplicationGroupChoice from authentication.views import get_user_by_stud_or_ntnu_email from committees.models import Committee +from internalportal.forms import InterviewEmailForm from inventory.models.item_loan import ItemLoan from news.models import Article, Event @@ -180,6 +181,32 @@ def test_func(self): return first_application_group_is_committee(self.get_object(), committee) +class ApplicationInterviewEmailView(UserPassesTestMixin, DetailView, FormView): + form_class = InterviewEmailForm + template_name = "internalportal/applications/interview_email_form.html" + model = Application + + def test_func(self): + committee = get_commitee_with_leader(self.request.user) + return first_application_group_is_committee(self.get_object(), committee) + + def form_valid(self, form): + application = self.get_object() + interview_email = render_to_string( + "internalportal/applications/interview_email.txt", + { + "interview": form.cleaned_data, + "application": application, + "application_group": ( + application.applicationgroupchoice_set.order_by("priority") + .first() + .group + ), + }, + ) + self.request.session["interview_email"] = interview_email + + class ApplicationApproveView(ApplicationRemoveView): template_name = "internalportal/applications/approve.html" From 68ac9fde970036e0d565c9163200c5906a7a695a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Sun, 26 Nov 2023 19:58:24 +0100 Subject: [PATCH 21/40] better styled and working form for writing email --- internalportal/forms.py | 8 ++-- .../applications/application.html | 2 +- .../applications/interview_email_form.html | 43 +++++++++++++++--- internalportal/views.py | 14 +++++- news/static/news/js/edit_event.js | 45 ------------------- news/templates/news/edit_event.html | 6 +-- 6 files changed, 58 insertions(+), 60 deletions(-) diff --git a/internalportal/forms.py b/internalportal/forms.py index f5ba72d9b..3f4c5928c 100644 --- a/internalportal/forms.py +++ b/internalportal/forms.py @@ -1,6 +1,8 @@ from django.db.models.fields import forms from django.utils.translation import gettext_lazy as _ +from news.forms import SplitDateTimeFieldCustom + class InterviewEmailForm(forms.Form): location = forms.CharField( @@ -13,11 +15,11 @@ class InterviewEmailForm(forms.Form): max_length=100, required=False, ) - start_time = forms.DateTimeField( - label=_("Tidspunkt"), + start_time = SplitDateTimeFieldCustom( + label=_("Starttidspunkt"), required=True, ) - end_time = forms.DateTimeField( + end_time = SplitDateTimeFieldCustom( label=_("Sluttidspunkt"), required=False, ) diff --git a/internalportal/templates/internalportal/applications/application.html b/internalportal/templates/internalportal/applications/application.html index c10871add..ce6ed6d3a 100644 --- a/internalportal/templates/internalportal/applications/application.html +++ b/internalportal/templates/internalportal/applications/application.html @@ -38,7 +38,7 @@

      {% trans "Intervjuprosessen" %}

    diff --git a/internalportal/templates/internalportal/applications/interview_email_form.html b/internalportal/templates/internalportal/applications/interview_email_form.html index eac10ec4e..1349362bd 100644 --- a/internalportal/templates/internalportal/applications/interview_email_form.html +++ b/internalportal/templates/internalportal/applications/interview_email_form.html @@ -7,21 +7,50 @@ {% endblock %} {% block content %} -
    +
    {% csrf_token %} - {{ form.as_p }} - +
    +
    + location_on + {{ form.location }} + + {{ form.location.errors }} +
    +
    + link + {{ form.location_link }} + + {{ form.location_link.errors }} +
    +
    + date_range + {{ form.start_time }} + + {{ form.start_time.errors }} +
    +
    +
    - {% if request.session.interview_email %} -
    -
    - {{ requeset.session.interview_email }} + {% if interview_email %} +
    +
    + {{ interview_email | safe | linebreaks }}
    + {% endif %}
    + + {% endblock %} diff --git a/internalportal/views.py b/internalportal/views.py index 14b4bb381..54bd11a00 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -181,11 +181,22 @@ def test_func(self): return first_application_group_is_committee(self.get_object(), committee) -class ApplicationInterviewEmailView(UserPassesTestMixin, DetailView, FormView): +class ApplicationInterviewEmailView(UserPassesTestMixin, FormView, DetailView): form_class = InterviewEmailForm template_name = "internalportal/applications/interview_email_form.html" model = Application + def get_success_url(self): + return reverse_lazy( + "internalportal:interview_email", kwargs={"pk": self.get_object().id} + ) + + def get_context_data(self, **kwargs): + self.object = self.get_object() + context = super().get_context_data(**kwargs) + context["interview_email"] = self.request.session.get("interview_email") + return context + def test_func(self): committee = get_commitee_with_leader(self.request.user) return first_application_group_is_committee(self.get_object(), committee) @@ -205,6 +216,7 @@ def form_valid(self, form): }, ) self.request.session["interview_email"] = interview_email + return super().form_valid(form) class ApplicationApproveView(ApplicationRemoveView): diff --git a/news/static/news/js/edit_event.js b/news/static/news/js/edit_event.js index 8dd1b403e..a7932c97f 100644 --- a/news/static/news/js/edit_event.js +++ b/news/static/news/js/edit_event.js @@ -1,49 +1,4 @@ document.addEventListener("DOMContentLoaded", function(event) { - var datepickers = document.querySelectorAll('.datepicker'); - - internationalization = { - months: [ - 'Januar', - 'Februar', - 'Mars', - 'April', - 'Mai', - 'Juni', - 'Juli', - 'August', - 'September', - 'Oktober', - 'November', - 'Desember' - ], - weekdays: [ - 'Søndag', - 'Mandag', - 'Tirsdag', - 'Onsdag', - 'Torsdag', - 'Fredag', - 'Lørdag' - ], - weekdaysShort: [ - 'Søn', - 'Man', - 'Tir', - 'Ons', - 'Tor', - 'Fre', - 'Lør' - ], - weekdaysAbbrev: ['S','M','T','O','T','F','L'] - } - options = { - format: 'yyyy-mm-dd', - firstDay: 1, - i18n: internationalization - } - var instance = M.Datepicker.init(datepickers, options); - - // Vis og gjem deler som relateres til påmeldinger const reg_boxes = document.getElementsByClassName('reg-box'); const reg_check = document.getElementsByName('registration')[0]; diff --git a/news/templates/news/edit_event.html b/news/templates/news/edit_event.html index 91d2c7632..6288a209d 100644 --- a/news/templates/news/edit_event.html +++ b/news/templates/news/edit_event.html @@ -48,8 +48,7 @@
    {% trans "Innhold" %}
    {{ form.main_content.errors }} {{ form.main_content }}
    -

    {% trans "Bare markdown støttes i dette feltet, html blir returnert som plaintext. Bilder - kan legges til ved drag-and-drop." %}

    +

    {% trans "Bare markdown støttes i dette feltet, html blir returnert som plaintext. Bilder kan legges til ved drag-and-drop." %}

    Markdown cheat-sheet

    @@ -252,6 +251,7 @@
    {% trans "Ferdig" %}
    + -{% endblock content %} \ No newline at end of file +{% endblock content %} From 8f73bcf7c473e2e74c2b50476989256001b5e017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Sun, 26 Nov 2023 20:22:34 +0100 Subject: [PATCH 22/40] add timepicker --- .../internalportal/applications/applications.html | 1 + .../internalportal/applications/interview_email.txt | 2 +- .../applications/interview_email_form.html | 2 +- internalportal/views.py | 9 ++++++++- news/forms.py | 5 +++++ news/templates/news/edit_event.html | 2 +- 6 files changed, 17 insertions(+), 4 deletions(-) diff --git a/internalportal/templates/internalportal/applications/applications.html b/internalportal/templates/internalportal/applications/applications.html index b1a3d496c..b23842075 100644 --- a/internalportal/templates/internalportal/applications/applications.html +++ b/internalportal/templates/internalportal/applications/applications.html @@ -16,6 +16,7 @@ {% endfor %} +
    {% endblock %} diff --git a/internalportal/templates/internalportal/applications/interview_email.txt b/internalportal/templates/internalportal/applications/interview_email.txt index ab381e8de..cce614c25 100644 --- a/internalportal/templates/internalportal/applications/interview_email.txt +++ b/internalportal/templates/internalportal/applications/interview_email.txt @@ -4,7 +4,7 @@ Tusen takk for din søknad hos Hackerspace NTNU! I forbindelse med opptaket hos Hackerspace NTNU, ønsker vi å kalle deg inn til et intervju. Intervjuet er en mulighet for oss til å bli enda bedre kjent med deg før det gjøres sluttvurderinger i opptaket, og en mulighet for deg til å stille spørsmål rundt opptaket, organisasjonen og annet dersom ønskelig. -Foreslått tidspunkt for intervjuet er {{ interview.start_time }} i {{ interview.location }}. +Foreslått tidspunkt for intervjuet er {{ interview.start_time }} i {% if interview.location_link %}{% endif %}{{ interview.location }}{% if interview.location_link %}{% endif %}. Vi ønsker gjerne at du bekrefter at tidspunktet passer, eller eventuelt svarer på mailen med timeplan / tidspunkter som passer bedre. diff --git a/internalportal/templates/internalportal/applications/interview_email_form.html b/internalportal/templates/internalportal/applications/interview_email_form.html index 1349362bd..a5eb8b15d 100644 --- a/internalportal/templates/internalportal/applications/interview_email_form.html +++ b/internalportal/templates/internalportal/applications/interview_email_form.html @@ -52,5 +52,5 @@ navigator.clipboard.writeText(copyText.innerText.trim()); } - + {% endblock %} diff --git a/internalportal/views.py b/internalportal/views.py index 54bd11a00..6f9e31209 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -14,6 +14,7 @@ from django.shortcuts import get_object_or_404, redirect from django.template.loader import render_to_string from django.urls import reverse, reverse_lazy +from django.utils import timezone from django.utils.translation import gettext_lazy as _ from django.views.generic import DeleteView, DetailView, ListView, TemplateView from django.views.generic.edit import BaseDetailView @@ -197,6 +198,12 @@ def get_context_data(self, **kwargs): context["interview_email"] = self.request.session.get("interview_email") return context + def get_initial(self): + initial = super().get_initial() + initial["start_time"] = timezone.now() + initial["end_time"] = timezone.now() + timedelta(minutes=20) + return initial + def test_func(self): committee = get_commitee_with_leader(self.request.user) return first_application_group_is_committee(self.get_object(), committee) @@ -258,7 +265,7 @@ def delete(self, request, *args, **kwargs): ) return HttpResponseRedirect( reverse_lazy( - "internalportal:application", kwargs={"pk": application.id} + "internalportal:approve_application", kwargs={"pk": application.id} ) ) diff --git a/news/forms.py b/news/forms.py index 73b86c335..cdd4aac27 100644 --- a/news/forms.py +++ b/news/forms.py @@ -88,6 +88,11 @@ class SplitDateTimeFieldCustom(forms.SplitDateTimeField): "class": "no-autoinit datepicker", } ), + time_attrs=( + { + "class": "no-autoinit timepicker", + } + ), date_format="%Y-%m-%d", time_format="%H:%M", ) diff --git a/news/templates/news/edit_event.html b/news/templates/news/edit_event.html index 6288a209d..ed447f74a 100644 --- a/news/templates/news/edit_event.html +++ b/news/templates/news/edit_event.html @@ -251,7 +251,7 @@
    {% trans "Ferdig" %}
    - + {% endblock content %} From 0dd276a5f7de8b7b7063716fd9a2e6882dd70577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Mon, 27 Nov 2023 00:00:18 +0100 Subject: [PATCH 23/40] translation and email header and back button --- .../applications/application.html | 2 +- .../applications/interview_email_form.html | 76 ++++++++++--------- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/internalportal/templates/internalportal/applications/application.html b/internalportal/templates/internalportal/applications/application.html index ce6ed6d3a..a46e851d5 100644 --- a/internalportal/templates/internalportal/applications/application.html +++ b/internalportal/templates/internalportal/applications/application.html @@ -32,7 +32,7 @@

    {% trans "Intervjuprosessen" %}

  • {% trans "Send mail om tidspunkt og sted for foreslått intervju" %}
  • {% trans "Hold intervju" %}
  • {% trans "Få kandidaten til å logge inn på nettsiden" %}
  • -
  • {% trans "Godkjenn kandidaten og send mail at de har kommet inn med HowToHack dokumentet på Drive" %}
  • +
  • {% trans "Godkjenn kandidaten og send mail at de har kommet inn med HowToHack dokumentet fra Google Drive" %}
  • {% trans "Legg kandidaten inn i kommunikasjonskanaler" %}
  • diff --git a/internalportal/templates/internalportal/applications/interview_email_form.html b/internalportal/templates/internalportal/applications/interview_email_form.html index a5eb8b15d..0136ab3d9 100644 --- a/internalportal/templates/internalportal/applications/interview_email_form.html +++ b/internalportal/templates/internalportal/applications/interview_email_form.html @@ -7,45 +7,53 @@ {% endblock %} {% block content %} -
    -
    - {% csrf_token %} -
    -
    - location_on - {{ form.location }} - - {{ form.location.errors }} + {% trans "E-post for intervju" as interview_email_header %} + {% include "website/page_header.html" with title=interview_email_header %} +
    +
    + + {% csrf_token %} +
    +
    + location_on + {{ form.location }} + + {{ form.location.errors }} +
    +
    + link + {{ form.location_link }} + + {{ form.location_link.errors }} +
    +
    + date_range + {{ form.start_time }} + + {{ form.start_time.errors }} +
    -
    - link - {{ form.location_link }} - - {{ form.location_link.errors }} -
    -
    - date_range - {{ form.start_time }} - - {{ form.start_time.errors }} -
    -
    - - + + - {% if interview_email %} -
    -
    - {{ interview_email | safe | linebreaks }} + {% if interview_email %} +
    +
    + {{ interview_email | safe | linebreaks }} +
    -
    - - {% endif %} + + {% endif %} +
    +
    - diff --git a/internalportal/views.py b/internalportal/views.py index cd9b834e6..cece2c2f2 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -84,6 +84,18 @@ def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) groups = self.get_object().applicationgroupchoice_set.all().order_by("priority") context["second_group"] = groups[1] if groups.count() > 1 else None + email_data = { + "application": self.get_object(), + "application_group": groups.first().group, + } + context["denied_email"] = render_to_string( + "internalportal/applications/denied_email.txt", + email_data, + ) + context["approved_email"] = render_to_string( + "internalportal/applications/approved_email.txt", + email_data, + ) return context diff --git a/inventory/locale/en/LC_MESSAGES/django.po b/inventory/locale/en/LC_MESSAGES/django.po index 47207ee50..5b2f5969a 100644 --- a/inventory/locale/en/LC_MESSAGES/django.po +++ b/inventory/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/inventory/locale/nb/LC_MESSAGES/django.po b/inventory/locale/nb/LC_MESSAGES/django.po index 86fd64189..ef1ca811b 100644 --- a/inventory/locale/nb/LC_MESSAGES/django.po +++ b/inventory/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/news/locale/en/LC_MESSAGES/django.po b/news/locale/en/LC_MESSAGES/django.po index 0c323e93d..a234fc532 100644 --- a/news/locale/en/LC_MESSAGES/django.po +++ b/news/locale/en/LC_MESSAGES/django.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/news/locale/nb/LC_MESSAGES/django.po b/news/locale/nb/LC_MESSAGES/django.po index 9d11d5db4..5e261cfba 100644 --- a/news/locale/nb/LC_MESSAGES/django.po +++ b/news/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/projectarchive/locale/en/LC_MESSAGES/django.po b/projectarchive/locale/en/LC_MESSAGES/django.po index f97591014..c855c5072 100644 --- a/projectarchive/locale/en/LC_MESSAGES/django.po +++ b/projectarchive/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/projectarchive/locale/nb/LC_MESSAGES/django.po b/projectarchive/locale/nb/LC_MESSAGES/django.po index b67e11cd8..b3293e1f3 100644 --- a/projectarchive/locale/nb/LC_MESSAGES/django.po +++ b/projectarchive/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/reservations/locale/en/LC_MESSAGES/django.po b/reservations/locale/en/LC_MESSAGES/django.po index a05777936..b84ad8676 100644 --- a/reservations/locale/en/LC_MESSAGES/django.po +++ b/reservations/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/reservations/locale/nb/LC_MESSAGES/django.po b/reservations/locale/nb/LC_MESSAGES/django.po index f67eb90fe..088d1ab01 100644 --- a/reservations/locale/nb/LC_MESSAGES/django.po +++ b/reservations/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/userprofile/locale/en/LC_MESSAGES/django.po b/userprofile/locale/en/LC_MESSAGES/django.po index 937f24454..e3da0cc51 100644 --- a/userprofile/locale/en/LC_MESSAGES/django.po +++ b/userprofile/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/userprofile/locale/nb/LC_MESSAGES/django.po b/userprofile/locale/nb/LC_MESSAGES/django.po index 720cf023b..9d4491d6b 100644 --- a/userprofile/locale/nb/LC_MESSAGES/django.po +++ b/userprofile/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/watchlist/locale/en/LC_MESSAGES/django.po b/watchlist/locale/en/LC_MESSAGES/django.po index 5cfb09c77..e4519c534 100644 --- a/watchlist/locale/en/LC_MESSAGES/django.po +++ b/watchlist/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/watchlist/locale/nb/LC_MESSAGES/django.po b/watchlist/locale/nb/LC_MESSAGES/django.po index e49c042f7..313fe0d09 100644 --- a/watchlist/locale/nb/LC_MESSAGES/django.po +++ b/watchlist/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/website/locale/en/LC_MESSAGES/django.po b/website/locale/en/LC_MESSAGES/django.po index d925945ec..d487548a5 100644 --- a/website/locale/en/LC_MESSAGES/django.po +++ b/website/locale/en/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/website/locale/nb/LC_MESSAGES/django.po b/website/locale/nb/LC_MESSAGES/django.po index 991f6447f..757393641 100644 --- a/website/locale/nb/LC_MESSAGES/django.po +++ b/website/locale/nb/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:10+0100\n" +"POT-Creation-Date: 2023-11-27 12:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" From df4e5ccc1a866932795b0fed1820ae02e6aede51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Mon, 27 Nov 2023 13:47:34 +0100 Subject: [PATCH 34/40] more translations to emails. debugging --- applications/locale/en/LC_MESSAGES/django.po | 2 +- applications/locale/nb/LC_MESSAGES/django.po | 2 +- files/locale/en/LC_MESSAGES/django.po | 2 +- files/locale/nb/LC_MESSAGES/django.po | 2 +- .../locale/en/LC_MESSAGES/django.po | 102 +++++++++--------- .../locale/nb/LC_MESSAGES/django.po | 72 ++++++------- .../applications/application.html | 24 +++-- .../applications/approved_email.txt | 4 +- .../applications/denied_email.txt | 2 +- .../applications/interview_email_form.html | 2 +- .../applications/text_box_copy.html | 14 +-- internalportal/views.py | 2 + inventory/locale/en/LC_MESSAGES/django.po | 2 +- inventory/locale/nb/LC_MESSAGES/django.po | 2 +- news/locale/en/LC_MESSAGES/django.po | 2 +- news/locale/nb/LC_MESSAGES/django.po | 2 +- .../locale/en/LC_MESSAGES/django.po | 2 +- .../locale/nb/LC_MESSAGES/django.po | 2 +- reservations/locale/en/LC_MESSAGES/django.po | 2 +- reservations/locale/nb/LC_MESSAGES/django.po | 2 +- userprofile/locale/en/LC_MESSAGES/django.po | 2 +- userprofile/locale/nb/LC_MESSAGES/django.po | 2 +- watchlist/locale/en/LC_MESSAGES/django.po | 2 +- watchlist/locale/nb/LC_MESSAGES/django.po | 2 +- website/locale/en/LC_MESSAGES/django.po | 2 +- website/locale/nb/LC_MESSAGES/django.po | 2 +- 26 files changed, 135 insertions(+), 123 deletions(-) diff --git a/applications/locale/en/LC_MESSAGES/django.po b/applications/locale/en/LC_MESSAGES/django.po index ad15416a1..d41329a47 100644 --- a/applications/locale/en/LC_MESSAGES/django.po +++ b/applications/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:41+0100\n" +"POT-Creation-Date: 2023-11-27 13:38+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/applications/locale/nb/LC_MESSAGES/django.po b/applications/locale/nb/LC_MESSAGES/django.po index de64b2b51..10d5d13a3 100644 --- a/applications/locale/nb/LC_MESSAGES/django.po +++ b/applications/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:41+0100\n" +"POT-Creation-Date: 2023-11-27 13:38+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/files/locale/en/LC_MESSAGES/django.po b/files/locale/en/LC_MESSAGES/django.po index 3e5c3f744..5911c5ad2 100644 --- a/files/locale/en/LC_MESSAGES/django.po +++ b/files/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:41+0100\n" +"POT-Creation-Date: 2023-11-27 13:38+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/files/locale/nb/LC_MESSAGES/django.po b/files/locale/nb/LC_MESSAGES/django.po index eb84b712b..d5144ff8e 100644 --- a/files/locale/nb/LC_MESSAGES/django.po +++ b/files/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:41+0100\n" +"POT-Creation-Date: 2023-11-27 13:38+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/internalportal/locale/en/LC_MESSAGES/django.po b/internalportal/locale/en/LC_MESSAGES/django.po index 170b93a91..5754853b7 100644 --- a/internalportal/locale/en/LC_MESSAGES/django.po +++ b/internalportal/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:41+0100\n" +"POT-Creation-Date: 2023-11-27 13:38+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -66,28 +66,26 @@ msgstr "Interview process" msgid "Les over søknaden" msgstr "Read through the application" -#: internalportal/templates/internalportal/applications/application.html:33 -msgid "Send mail om tidspunkt og sted for foreslått intervju" -msgstr "Send email about proposed interview time and location" - #: internalportal/templates/internalportal/applications/application.html:34 +msgid "Send e-post om intervju" +msgstr "Send email about interview" + +#: internalportal/templates/internalportal/applications/application.html:36 msgid "Hold intervju" msgstr "Conduct interview" -#: internalportal/templates/internalportal/applications/application.html:35 -#, fuzzy -msgid "E-post for avslå" -msgstr "Email for interview" +#: internalportal/templates/internalportal/applications/application.html:37 +msgid "Gi beskjed om kandidaten ikke er videre i intervjuprosessen" +msgstr "Notify if the candidate is not proceeding in the interview process." -#: internalportal/templates/internalportal/applications/application.html:40 +#: internalportal/templates/internalportal/applications/application.html:39 +msgid "E-post for å avslå" +msgstr "Email to deny" + +#: internalportal/templates/internalportal/applications/application.html:45 msgid "Få kandidaten til å logge inn på nettsiden" msgstr "Have the candidate log in to the website" -#: internalportal/templates/internalportal/applications/application.html:41 -#, fuzzy -msgid "E-post for godkjent" -msgstr "Email for interview" - #: internalportal/templates/internalportal/applications/application.html:46 msgid "" "Godkjenn kandidaten og send mail at de har kommet inn med HowToHack " @@ -96,39 +94,39 @@ msgstr "" "Approve the candidate and send an email that they have been accepted with " "the HowToHack document from Google Drive" -#: internalportal/templates/internalportal/applications/application.html:47 +#: internalportal/templates/internalportal/applications/application.html:48 +msgid "E-post for å godkjenne" +msgstr "Email to approve" + +#: internalportal/templates/internalportal/applications/application.html:54 msgid "Legg kandidaten inn i kommunikasjonskanaler" msgstr "Add the candidate to communication channels" -#: internalportal/templates/internalportal/applications/application.html:52 -msgid "Send e-post om intervju" -msgstr "Send email about interview" - -#: internalportal/templates/internalportal/applications/application.html:57 +#: internalportal/templates/internalportal/applications/application.html:61 #: internalportal/templates/internalportal/applications/applications.html:23 msgid "Tilbake" msgstr "Back" -#: internalportal/templates/internalportal/applications/application.html:58 +#: internalportal/templates/internalportal/applications/application.html:62 #: internalportal/templates/internalportal/applications/approve.html:49 msgid "Godkjenn" msgstr "Approve" -#: internalportal/templates/internalportal/applications/application.html:59 +#: internalportal/templates/internalportal/applications/application.html:63 msgid "Fjern" msgstr "Remove" -#: internalportal/templates/internalportal/applications/application.html:61 -#: internalportal/templates/internalportal/applications/application.html:66 +#: internalportal/templates/internalportal/applications/application.html:65 +#: internalportal/templates/internalportal/applications/application.html:70 msgid "Send videre" msgstr "Forward" -#: internalportal/templates/internalportal/applications/application.html:64 +#: internalportal/templates/internalportal/applications/application.html:68 #, fuzzy msgid "Er du sikker på at du vil sende søknaden videre?" msgstr "Are you sure you want to send the application to the next group?" -#: internalportal/templates/internalportal/applications/application.html:65 +#: internalportal/templates/internalportal/applications/application.html:69 #, fuzzy msgid "Søknaden sendes til" msgstr "The application is sent to" @@ -197,10 +195,10 @@ msgstr "Email" msgid "Gå tilbake" msgstr "Go back" -#: internalportal/templates/internalportal/applications/approved_email.txt:1 +#: internalportal/templates/internalportal/applications/approved_email.txt:2 #, python-format msgid "" -" Hei %(name)s,\n" +"Hei %(name)s,\n" "\n" "Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige " "intervjuet.\n" @@ -212,23 +210,27 @@ msgid "" "avslå tilbudet om medlemskap. \n" "\n" "Med vennlig hilsen,\n" -"%(application_group)s " +"%(application_group)s" msgstr "" " Hi %(name)s,\n" "\n" -"Thank you for your application to Hackerspace NTNU for the pleasant interview.\n" +"Thank you for your application to Hackerspace NTNU and for the pleasant " +"interview.\n" "\n" -"You made a positive impression during the interview, and we would like to offer you membership in Hackerspace NTNU in Hackerspace NTNU %(application_group)s.\n" +"You made a positive impression during the interview, and we would like to " +"offer you membership in Hackerspace NTNU in Hackerspace NTNU " +"%(application_group)s.\n" "\n" -"We would appreciate it if you could respond to this email by either accepting or declining the membership offer.\n" +"We would appreciate it if you could respond to this email by either " +"accepting or declining the membership offer.\n" "\n" "Best regards,\n" "%(application_group)s " -#: internalportal/templates/internalportal/applications/denied_email.txt:1 +#: internalportal/templates/internalportal/applications/denied_email.txt:2 #, python-format msgid "" -" Hei %(name)s,\n" +"Hei %(name)s,\n" "\n" "Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige " "intervjuet.\n" @@ -241,16 +243,18 @@ msgid "" msgstr "" " Hi %(name)s,\n" "\n" -"Thank you for your application to Hackerspace NTNU for the pleasant interview.\n" +"Thank you for your application to Hackerspace NTNU and for the pleasant " +"interview.\n" "\n" -"Unfortunately, you have not been selected for a spot in Hackerspace %(application_group)s.\n" +"Unfortunately, you have not been selected for a spot in Hackerspace " +"%(application_group)s.\n" "I wish you the best of luck with your studies moving forward.\n" "\n" "Best regards,\n" "%(application_group)s " -#: internalportal/templates/internalportal/applications/interview_email.txt:1 -#, fuzzy, python-format +#: internalportal/templates/internalportal/applications/interview_email.txt:2 +#, python-format msgid "" "Hei %(application_name)s,\n" "Tusen takk for din søknad hos Hackerspace NTNU!\n" @@ -276,7 +280,7 @@ msgstr "" "\n" "The proposed time for the interview is %(start_time)s in " -#: internalportal/templates/internalportal/applications/interview_email.txt:12 +#: internalportal/templates/internalportal/applications/interview_email.txt:13 msgid "Med vennlig hilsen" msgstr "Best regards" @@ -308,7 +312,7 @@ msgstr "Year" msgid "Søknad motatt" msgstr "Application received" -#: internalportal/templates/internalportal/applications/text_box_copy.html:9 +#: internalportal/templates/internalportal/applications/text_box_copy.html:10 #: internalportal/templates/internalportal/door-access-member-list.html:6 msgid "Kopier til utklippstavle" msgstr "Copy to clipboard" @@ -385,33 +389,33 @@ msgstr "Applicants" msgid "venter" msgstr "waiting" -#: internalportal/views.py:108 +#: internalportal/views.py:110 msgid "Søknad sendt videre til neste gruppe" msgstr "Application forwarded to the next group" -#: internalportal/views.py:117 +#: internalportal/views.py:119 msgid "Søknaden finnes ikke" msgstr "The application does not exist" -#: internalportal/views.py:133 +#: internalportal/views.py:135 msgid "Søknaden har ingen flere grupper å gå til" msgstr "The application has no more groups to go to" -#: internalportal/views.py:143 +#: internalportal/views.py:145 #, python-brace-format msgid "Gruppen {group_name} finnes ikke. Kontakt administrator." msgstr "The group {group_name} does not exist. Contact the administrator." -#: internalportal/views.py:160 +#: internalportal/views.py:162 #, fuzzy, python-brace-format msgid "Gruppen {group} har ingen ledere. Kontakt administrator." -msgstr "The group {group_name} does not exist. Contact the administrator." +msgstr "The group {group} does not have any leaders. Contact the administrator." -#: internalportal/views.py:171 +#: internalportal/views.py:173 msgid "Søknad sendt videre" msgstr "Application forwarded" -#: internalportal/views.py:272 +#: internalportal/views.py:274 msgid "Få brukeren til å logge inn med Feide først og bruk søkerens ntnu-mail." msgstr "" "Have the user log in with Feide first and use the applicant's NTNU email." diff --git a/internalportal/locale/nb/LC_MESSAGES/django.po b/internalportal/locale/nb/LC_MESSAGES/django.po index 5cbf1c820..e7b095786 100644 --- a/internalportal/locale/nb/LC_MESSAGES/django.po +++ b/internalportal/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 12:41+0100\n" +"POT-Creation-Date: 2023-11-27 13:38+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -66,24 +66,24 @@ msgstr "" msgid "Les over søknaden" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:33 -msgid "Send mail om tidspunkt og sted for foreslått intervju" +#: internalportal/templates/internalportal/applications/application.html:34 +msgid "Send e-post om intervju" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:34 +#: internalportal/templates/internalportal/applications/application.html:36 msgid "Hold intervju" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:35 -msgid "E-post for avslå" +#: internalportal/templates/internalportal/applications/application.html:37 +msgid "Gi beskjed om kandidaten ikke er videre i intervjuprosessen" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:40 -msgid "Få kandidaten til å logge inn på nettsiden" +#: internalportal/templates/internalportal/applications/application.html:39 +msgid "E-post for å avslå" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:41 -msgid "E-post for godkjent" +#: internalportal/templates/internalportal/applications/application.html:45 +msgid "Få kandidaten til å logge inn på nettsiden" msgstr "" #: internalportal/templates/internalportal/applications/application.html:46 @@ -92,38 +92,38 @@ msgid "" "dokumentet fra Google Drive" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:47 -msgid "Legg kandidaten inn i kommunikasjonskanaler" +#: internalportal/templates/internalportal/applications/application.html:48 +msgid "E-post for å godkjenne" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:52 -msgid "Send e-post om intervju" +#: internalportal/templates/internalportal/applications/application.html:54 +msgid "Legg kandidaten inn i kommunikasjonskanaler" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:57 +#: internalportal/templates/internalportal/applications/application.html:61 #: internalportal/templates/internalportal/applications/applications.html:23 msgid "Tilbake" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:58 +#: internalportal/templates/internalportal/applications/application.html:62 #: internalportal/templates/internalportal/applications/approve.html:49 msgid "Godkjenn" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:59 +#: internalportal/templates/internalportal/applications/application.html:63 msgid "Fjern" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:61 -#: internalportal/templates/internalportal/applications/application.html:66 +#: internalportal/templates/internalportal/applications/application.html:65 +#: internalportal/templates/internalportal/applications/application.html:70 msgid "Send videre" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:64 +#: internalportal/templates/internalportal/applications/application.html:68 msgid "Er du sikker på at du vil sende søknaden videre?" msgstr "" -#: internalportal/templates/internalportal/applications/application.html:65 +#: internalportal/templates/internalportal/applications/application.html:69 msgid "Søknaden sendes til" msgstr "" @@ -189,10 +189,10 @@ msgstr "" msgid "Gå tilbake" msgstr "" -#: internalportal/templates/internalportal/applications/approved_email.txt:1 +#: internalportal/templates/internalportal/applications/approved_email.txt:2 #, python-format msgid "" -" Hei %(name)s,\n" +"Hei %(name)s,\n" "\n" "Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige " "intervjuet.\n" @@ -204,13 +204,13 @@ msgid "" "avslå tilbudet om medlemskap. \n" "\n" "Med vennlig hilsen,\n" -"%(application_group)s " +"%(application_group)s" msgstr "" -#: internalportal/templates/internalportal/applications/denied_email.txt:1 +#: internalportal/templates/internalportal/applications/denied_email.txt:2 #, python-format msgid "" -" Hei %(name)s,\n" +"Hei %(name)s,\n" "\n" "Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige " "intervjuet.\n" @@ -222,7 +222,7 @@ msgid "" "%(application_group)s" msgstr "" -#: internalportal/templates/internalportal/applications/interview_email.txt:1 +#: internalportal/templates/internalportal/applications/interview_email.txt:2 #, python-format msgid "" "Hei %(application_name)s,\n" @@ -238,7 +238,7 @@ msgid "" "Foreslått tidspunkt for intervjuet er %(start_time)s i " msgstr "" -#: internalportal/templates/internalportal/applications/interview_email.txt:12 +#: internalportal/templates/internalportal/applications/interview_email.txt:13 msgid "Med vennlig hilsen" msgstr "" @@ -270,7 +270,7 @@ msgstr "" msgid "Søknad motatt" msgstr "" -#: internalportal/templates/internalportal/applications/text_box_copy.html:9 +#: internalportal/templates/internalportal/applications/text_box_copy.html:10 #: internalportal/templates/internalportal/door-access-member-list.html:6 msgid "Kopier til utklippstavle" msgstr "" @@ -347,32 +347,32 @@ msgstr "" msgid "venter" msgstr "" -#: internalportal/views.py:108 +#: internalportal/views.py:110 msgid "Søknad sendt videre til neste gruppe" msgstr "" -#: internalportal/views.py:117 +#: internalportal/views.py:119 msgid "Søknaden finnes ikke" msgstr "" -#: internalportal/views.py:133 +#: internalportal/views.py:135 msgid "Søknaden har ingen flere grupper å gå til" msgstr "" -#: internalportal/views.py:143 +#: internalportal/views.py:145 #, python-brace-format msgid "Gruppen {group_name} finnes ikke. Kontakt administrator." msgstr "" -#: internalportal/views.py:160 +#: internalportal/views.py:162 #, python-brace-format msgid "Gruppen {group} har ingen ledere. Kontakt administrator." msgstr "" -#: internalportal/views.py:171 +#: internalportal/views.py:173 msgid "Søknad sendt videre" msgstr "" -#: internalportal/views.py:272 +#: internalportal/views.py:274 msgid "Få brukeren til å logge inn med Feide først og bruk søkerens ntnu-mail." msgstr "" diff --git a/internalportal/templates/internalportal/applications/application.html b/internalportal/templates/internalportal/applications/application.html index 3d632fa01..3da529147 100644 --- a/internalportal/templates/internalportal/applications/application.html +++ b/internalportal/templates/internalportal/applications/application.html @@ -30,27 +30,31 @@

    {% trans "Intervjuprosessen" %}

    1. {% trans "Les over søknaden" %}
    2. -
    3. {% trans "Send mail om tidspunkt og sted for foreslått intervju" %}
    4. +
    5. + {% trans "Send e-post om intervju" %} +
    6. {% trans "Hold intervju" %}
    7. -
    8. {% trans "E-post for avslå" %} -
    9. {% trans "Gi beskjed om kandidaten ikke er videre i intervjuprosessen" %}
      + + {% trans "E-post for å avslå" %} + +
    10. {% trans "Få kandidaten til å logge inn på nettsiden" %}
    11. -
    12. {% trans "E-post for godkjent" %} +
    13. {% trans "Godkjenn kandidaten og send mail at de har kommet inn med HowToHack dokumentet fra Google Drive" %}
      + + {% trans "E-post for å godkjenne" %} +
    14. -
    15. {% trans "Godkjenn kandidaten og send mail at de har kommet inn med HowToHack dokumentet fra Google Drive" %}
    16. {% trans "Legg kandidaten inn i kommunikasjonskanaler" %}
    -
    diff --git a/internalportal/templates/internalportal/applications/approved_email.txt b/internalportal/templates/internalportal/applications/approved_email.txt index 60930b12e..4531b6427 100644 --- a/internalportal/templates/internalportal/applications/approved_email.txt +++ b/internalportal/templates/internalportal/applications/approved_email.txt @@ -1,5 +1,5 @@ {% load i18n %} -{% blocktranslate with name=application.name %} Hei {{ name }}, +{% blocktranslate with name=application.name %}Hei {{ name }}, Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige intervjuet. @@ -8,4 +8,4 @@ Du gjorde et godt inntrykk på intervjuet og vi ønsker å tilby deg medlemskap Vi ønsker gjerne at du svarer på denne mailen med å enten akseptere eller avslå tilbudet om medlemskap. Med vennlig hilsen, -{{ application_group }} {% endblocktranslate %} +{{ application_group }}{% endblocktranslate %} diff --git a/internalportal/templates/internalportal/applications/denied_email.txt b/internalportal/templates/internalportal/applications/denied_email.txt index 6d8e2c2c4..e6db08209 100644 --- a/internalportal/templates/internalportal/applications/denied_email.txt +++ b/internalportal/templates/internalportal/applications/denied_email.txt @@ -1,5 +1,5 @@ {% load i18n %} -{% blocktranslate with name=application.name %} Hei {{ name }}, +{% blocktranslate with name=application.name %}Hei {{ name }}, Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige intervjuet. diff --git a/internalportal/templates/internalportal/applications/interview_email_form.html b/internalportal/templates/internalportal/applications/interview_email_form.html index f90785017..45cadb45e 100644 --- a/internalportal/templates/internalportal/applications/interview_email_form.html +++ b/internalportal/templates/internalportal/applications/interview_email_form.html @@ -37,7 +37,7 @@ {% if interview_email %} - {% include "internalportal/applications/text-box-copy.html" with text=interview_email %} + {% include "internalportal/applications/text_box_copy.html" with text=interview_email %} {% endif %}
    diff --git a/internalportal/templates/internalportal/applications/text_box_copy.html b/internalportal/templates/internalportal/applications/text_box_copy.html index 22fc919e6..d3fa5c23b 100644 --- a/internalportal/templates/internalportal/applications/text_box_copy.html +++ b/internalportal/templates/internalportal/applications/text_box_copy.html @@ -1,13 +1,15 @@ {% load i18n %} -
    -
    - {{ text | safe | linebreaks }} +
    +
    +
    + {{ text | safe | linebreaks }} +
    +
    - {% endblock %} diff --git a/internalportal/templates/internalportal/internalportal.html b/internalportal/templates/internalportal/internalportal.html index 17738a07e..adad6188b 100644 --- a/internalportal/templates/internalportal/internalportal.html +++ b/internalportal/templates/internalportal/internalportal.html @@ -169,17 +169,19 @@
    {% trans "Medlemsliste for dørtilgang" %}
    {% endif %} - + {% if user_is_leader %} + + {% endif %}
    diff --git a/internalportal/views.py b/internalportal/views.py index efeaef182..0c04454e1 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -54,6 +54,7 @@ def get_context_data(self, *args, **kwargs): ) committee = get_commitee_with_leader(self.request.user) context["new_applicants_no"] = get_applications_for_committee(committee).count() + context["user_is_leader"] = committee is not None return context From 3a6b4460aa82f095aa00157a55e84e3fd6e8b79d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Tue, 28 Nov 2023 17:36:05 +0100 Subject: [PATCH 38/40] delete weirdly created file I dont understand --- ' | 15 --------------- .../applications/interview_email.txt | 3 +-- 2 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 ' diff --git a/' b/' deleted file mode 100644 index b1f79ddbd..000000000 --- a/' +++ /dev/null @@ -1,15 +0,0 @@ -{% blocktranslate with application_name=application.name start_time=interview.start_time %}Hei {{ application_name }}, -Tusen takk for din søknad hos Hackerspace NTNU! - - -I forbindelse med opptaket hos Hackerspace NTNU, ønsker vi å kalle deg inn til et intervju. Intervjuet er en mulighet for oss til å bli enda bedre kjent med deg før det gjøres sluttvurderinger i opptaket, og en mulighet for deg til å stille spørsmål rundt opptaket, organisasjonen og annet dersom ønskelig. - -Foreslått tidspunkt for intervjuet er {{ start_time }} i {% endblocktranslate %}{% if interview.location_link %}{% endif %}{{ interview.location }}{% if interview.location_link %}{% endif %}. - - -Vi ønsker gjerne at du bekrefter at tidspunktet passer, eller eventuelt svarer på mailen med timeplan / tidspunkter som passer bedre. - -{% trans "Med vennlig hilsen" %}, -{{ application_group }} -Hackerspace NTNU - diff --git a/internalportal/templates/internalportal/applications/interview_email.txt b/internalportal/templates/internalportal/applications/interview_email.txt index 6e991a675..00413a9b4 100644 --- a/internalportal/templates/internalportal/applications/interview_email.txt +++ b/internalportal/templates/internalportal/applications/interview_email.txt @@ -1,5 +1,4 @@ -{% load i18n %} -{% blocktranslate with application_name=application.name start_time=interview.start_time %}Hei {{ application_name }}, +{% load i18n %}{% blocktranslate with application_name=application.name start_time=interview.start_time %}Hei {{ application_name }}, Tusen takk for din søknad hos Hackerspace NTNU! From 1827f4796d6e201314aaf73e4c4f1fd549d4781c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= Date: Tue, 28 Nov 2023 17:53:35 +0100 Subject: [PATCH 39/40] remove static/ from gitignore to add to new static files --- .gitignore | 1 - .../internalportal/css/applications.css | 15 ++++++ website/static/website/js/datetimepicker.js | 53 +++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 internalportal/static/internalportal/css/applications.css create mode 100644 website/static/website/js/datetimepicker.js diff --git a/.gitignore b/.gitignore index f8f4416f7..c159d292b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ profilepictures/ env/ venv/ .vscode/ -static/ **/__pycache__ /static/ diff --git a/internalportal/static/internalportal/css/applications.css b/internalportal/static/internalportal/css/applications.css new file mode 100644 index 000000000..8162455fc --- /dev/null +++ b/internalportal/static/internalportal/css/applications.css @@ -0,0 +1,15 @@ +.application-info { + display: flex; + flex-direction: column; + gap: 1rem; + margin-bottom: 10px; +} + +.application-button-bar { + margin-top: 2rem; + margin-bottom: 2rem; + display: flex; + gap: 4rem; + flex-wrap: wrap; + justify-content: space-around; +} diff --git a/website/static/website/js/datetimepicker.js b/website/static/website/js/datetimepicker.js new file mode 100644 index 000000000..060267a67 --- /dev/null +++ b/website/static/website/js/datetimepicker.js @@ -0,0 +1,53 @@ +document.addEventListener("DOMContentLoaded", function() { + var datepickers = document.querySelectorAll('.datepicker'); + + internationalization = { + months: [ + 'Januar', + 'Februar', + 'Mars', + 'April', + 'Mai', + 'Juni', + 'Juli', + 'August', + 'September', + 'Oktober', + 'November', + 'Desember' + ], + weekdays: [ + 'Søndag', + 'Mandag', + 'Tirsdag', + 'Onsdag', + 'Torsdag', + 'Fredag', + 'Lørdag' + ], + weekdaysShort: [ + 'Søn', + 'Man', + 'Tir', + 'Ons', + 'Tor', + 'Fre', + 'Lør' + ], + weekdaysAbbrev: ['S','M','T','O','T','F','L'] + } + options = { + format: 'yyyy-mm-dd', + firstDay: 1, + i18n: internationalization + } + M.Datepicker.init(datepickers, options); + + + var elems = document.querySelectorAll('.timepicker'); + options = { + twelveHour: false, + format: 'HH:mm', + }; + M.Timepicker.init(elems, options); +}); From d25222b7f9a67bb6ede79dc95dd7d17311397c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= <70779496+CJGutz@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:54:52 +0100 Subject: [PATCH 40/40] change to group names --- applications/admin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/admin.py b/applications/admin.py index 08b8a00ad..cf3f44cc5 100644 --- a/applications/admin.py +++ b/applications/admin.py @@ -25,10 +25,10 @@ class ApplicationAdmin(BaseApplicationAdmin): list_display = [ "name", "email", - "get_application_groups", + "groups", ] - def get_application_groups(self, obj): + def groups(self, obj): return ", ".join( [ group.name