1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2024-11-26 18:37:12 +00:00

Improve WEI UI

This commit is contained in:
Yohann D'ANELLO 2020-04-18 03:27:12 +02:00
parent d7da876a23
commit 0c9409fd4b
8 changed files with 105 additions and 22 deletions

View File

@ -1,11 +1,34 @@
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from permission.backends import PermissionBackend from django.forms import HiddenInput
from django.views.generic import UpdateView
from .backends import PermissionBackend
class ProtectQuerysetMixin: class ProtectQuerysetMixin:
"""
Ensure that the user has the right to see or update objects.
Display 404 error if the user can't see an object, remove the fields the user can't
update on an update form (useful if the user can't change only specified fields).
"""
def get_queryset(self, **kwargs): def get_queryset(self, **kwargs):
qs = super().get_queryset(**kwargs) qs = super().get_queryset(**kwargs)
return qs.filter(PermissionBackend.filter_queryset(self.request.user, qs.model, "view")) return qs.filter(PermissionBackend.filter_queryset(self.request.user, qs.model, "view"))
def get_form(self, form_class=None):
form = super().get_form(form_class)
if not isinstance(self, UpdateView):
return form
# If we are in an UpdateView, we display only the fields the user has right to see.
# No worry if the user change the hidden fields: a 403 error will be performed if the user tries to make
# a custom request.
# We could also delete the field, but some views might be affected.
for key in form.base_fields:
if not PermissionBackend.check_perm(self.request.user, "wei.change_weiregistration_" + key, self.object):
form.fields[key].widget = HiddenInput()
return form

View File

@ -27,6 +27,10 @@ class WEIClub(Club):
verbose_name=_("date end"), verbose_name=_("date end"),
) )
@property
def is_current_wei(self):
return not WEIClub.objects.filter(date_start__gt=self.date_start).exists()
def update_membership_dates(self): def update_membership_dates(self):
""" """
We can't join the WEI next years. We can't join the WEI next years.
@ -216,6 +220,13 @@ class WEIRegistration(models.Model):
""" """
self.information_json = json.dumps(information) self.information_json = json.dumps(information)
@property
def is_validated(self):
try:
return self.membership is not None
except KeyError:
return False
def __str__(self): def __str__(self):
return str(self.user) return str(self.user)

View File

@ -3,13 +3,14 @@
from django.urls import path from django.urls import path
from .views import WEIListView, WEICreateView, WEIDetailView, WEIUpdateView,\ from .views import CurrentWEIDetailView, WEIListView, WEICreateView, WEIDetailView, WEIUpdateView,\
BusCreateView, BusManageView, BusUpdateView, BusTeamCreateView, BusTeamManageView, BusTeamUpdateView,\ BusCreateView, BusManageView, BusUpdateView, BusTeamCreateView, BusTeamManageView, BusTeamUpdateView,\
WEIRegister1AView, WEIRegister2AView, WEIUpdateRegistrationView, WEIValidateRegistrationView WEIRegister1AView, WEIRegister2AView, WEIUpdateRegistrationView, WEIValidateRegistrationView
app_name = 'wei' app_name = 'wei'
urlpatterns = [ urlpatterns = [
path('detail/', CurrentWEIDetailView.as_view(), name="current_wei_detail"),
path('list/', WEIListView.as_view(), name="wei_list"), path('list/', WEIListView.as_view(), name="wei_list"),
path('create/', WEICreateView.as_view(), name="wei_create"), path('create/', WEICreateView.as_view(), name="wei_create"),
path('detail/<int:pk>/', WEIDetailView.as_view(), name="wei_detail"), path('detail/<int:pk>/', WEIDetailView.as_view(), name="wei_detail"),

View File

@ -6,8 +6,9 @@ from datetime import datetime, date
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models import Q from django.db.models import Q
from django.shortcuts import redirect
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic import DetailView, UpdateView, CreateView from django.views.generic import DetailView, UpdateView, CreateView, View
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django_tables2 import SingleTableView from django_tables2 import SingleTableView
from member.models import Membership, Club from member.models import Membership, Club
@ -21,12 +22,19 @@ from .forms import WEIForm, WEIRegistrationForm, BusForm, BusTeamForm, WEIMember
from .tables import WEITable, WEIRegistrationTable, BusTable, BusTeamTable, WEIMembershipTable from .tables import WEITable, WEIRegistrationTable, BusTable, BusTeamTable, WEIMembershipTable
class CurrentWEIDetailView(LoginRequiredMixin, View):
def get(self, *args, **kwargs):
wei = WEIClub.objects.order_by('date_start').last()
return redirect(reverse_lazy('wei:wei_detail', args=(wei.pk,)))
class WEIListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): class WEIListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
""" """
List existing WEI List existing WEI
""" """
model = WEIClub model = WEIClub
table_class = WEITable table_class = WEITable
ordering = '-year'
class WEICreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView): class WEICreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
@ -85,6 +93,13 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
pre_registrations_table.paginate(per_page=20, page=self.request.GET.get('membership-page', 1)) pre_registrations_table.paginate(per_page=20, page=self.request.GET.get('membership-page', 1))
context['pre_registrations'] = pre_registrations_table context['pre_registrations'] = pre_registrations_table
my_registration = WEIRegistration.objects.filter(wei=club, user=self.request.user)
if my_registration.exists():
my_registration = my_registration.get()
else:
my_registration = None
context["my_registration"] = my_registration
buses = Bus.objects.filter(PermissionBackend.filter_queryset(self.request.user, Bus, "view"))\ buses = Bus.objects.filter(PermissionBackend.filter_queryset(self.request.user, Bus, "view"))\
.filter(wei=self.object) .filter(wei=self.object)
bus_table = BusTable(data=buses, prefix="bus-") bus_table = BusTable(data=buses, prefix="bus-")
@ -98,8 +113,14 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
date_end=datetime.now().date(), date_end=datetime.now().date(),
fee=0, fee=0,
) )
context["can_add_members"] = PermissionBackend() \ context["can_add_members"] = PermissionBackend \
.has_perm(self.request.user, "member.add_membership", empty_membership) .check_perm(self.request.user, "member.add_membership", empty_membership)
empty_bus = Bus(
wei=club,
name="",
)
context["can_add_bus"] = PermissionBackend.check_perm(self.request.user, "wei.add_bus", empty_bus)
return context return context
@ -261,6 +282,7 @@ class WEIRegister1AView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['title'] = _("Register 1A") context['title'] = _("Register 1A")
context['club'] = WEIClub.objects.get(pk=self.kwargs["wei_pk"])
return context return context
def get_form(self, form_class=None): def get_form(self, form_class=None):
@ -291,6 +313,7 @@ class WEIRegister2AView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['title'] = _("Register 2A+") context['title'] = _("Register 2A+")
context['club'] = WEIClub.objects.get(pk=self.kwargs["wei_pk"])
return context return context
def get_form(self, form_class=None): def get_form(self, form_class=None):
@ -319,8 +342,14 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update
model = WEIRegistration model = WEIRegistration
form_class = WEIRegistrationForm form_class = WEIRegistrationForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["club"] = self.object.wei
return context
def get_form(self, form_class=None): def get_form(self, form_class=None):
form = super().get_form(form_class) form = super().get_form(form_class)
if "user" in form.fields:
del form.fields["user"] del form.fields["user"]
return form return form

View File

@ -112,7 +112,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
</li> </li>
{% endif %} {% endif %}
<li class="nav-item active"> <li class="nav-item active">
<a class="nav-link" href="{% url 'wei:wei_list' %}"><i class="fa fa-bus"></i> {% trans 'WEI' %}</a> <a class="nav-link" href="{% url 'wei:current_wei_detail' %}"><i class="fa fa-bus"></i> {% trans 'WEI' %}</a>
</li> </li>
</ul> </ul>
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">

View File

@ -54,19 +54,24 @@
</dl> </dl>
</div> </div>
<div class="card-footer text-center"> <div class="card-footer text-center">
{% if True %}
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:wei_list' %}"> {% trans "WEI list" %}</a>
{% endif %}
{% if club.is_current_wei %}
{% if can_add_members %} {% if can_add_members %}
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:wei_register_1A' wei_pk=club.pk %}"> {% trans "Register 1A" %}</a> <a class="btn btn-primary btn-sm my-1" href="{% url 'wei:wei_register_1A' wei_pk=club.pk %}"> {% trans "Register 1A" %}</a>
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:wei_register_2A' wei_pk=club.pk %}"> {% trans "Register 2A+" %}</a> <a class="btn btn-primary btn-sm my-1" href="{% url 'wei:wei_register_2A' wei_pk=club.pk %}"> {% trans "Register 2A+" %}</a>
{% endif %} {% endif %}
{% if ".change_"|has_perm:club %} {% if "wei.change_"|has_perm:club %}
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:wei_update' pk=club.pk %}"> {% trans "Edit" %}</a> <a class="btn btn-primary btn-sm my-1" href="{% url 'wei:wei_update' pk=club.pk %}"> {% trans "Edit" %}</a>
{% endif %} {% endif %}
{% if True %} {% if can_add_bus %}
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:add_bus' pk=club.pk %}"> {% trans "Add bus" %}</a> <a class="btn btn-primary btn-sm my-1" href="{% url 'wei:add_bus' pk=club.pk %}"> {% trans "Add bus" %}</a>
{% endif %} {% endif %}
{% url 'wei:wei_detail' club.pk as club_detail_url %} {% url 'wei:wei_detail' club.pk as club_detail_url %}
{%if request.path_info != club_detail_url %} {%if request.path_info != club_detail_url %}
<a class="btn btn-primary btn-sm my-1" href="{{ club_detail_url }}">{% trans 'View WEI' %}</a> <a class="btn btn-primary btn-sm my-1" href="{{ club_detail_url }}">{% trans 'View WEI' %}</a>
{% endif %} {% endif %}
{% endif %}
</div> </div>
</div> </div>

View File

@ -55,6 +55,16 @@
in iaculis. Neque gravida in fermentum et sollicitudin ac orci. in iaculis. Neque gravida in fermentum et sollicitudin ac orci.
</p> </p>
</div> </div>
{% if club.is_current_wei %}
<div class="card-footer text-center">
{% if not my_registration %}
<a href="{% url "wei:wei_register_1A" wei_pk=club.pk %}"><button class="btn btn-success">{% trans "Register to the WEI!" %}</button></a>
{% elif my_registration.is_validated %}
<a href="{% url "wei:wei_update_registration" pk=user.pk %}"><button class="btn btn-warning">{% trans "Update my registration" %}</button></a>
{% endif %}
</div>
{% endif %}
</div> </div>
<hr> <hr>

View File

@ -1,8 +1,12 @@
{% extends "base.html" %} {% extends "member/noteowner_detail.html" %}
{% load static %}
{% load i18n %} {% load i18n %}
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% block content %}
{% block profile_info %}
{% include "wei/weiclub_info.html" %}
{% endblock %}
{% block profile_content %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
{{ form|crispy }} {{ form|crispy }}