mirror of https://gitlab.crans.org/bde/nk20
Dynamic user research
This commit is contained in:
parent
2853fe252b
commit
5eb08fd822
|
@ -1,33 +0,0 @@
|
||||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
from crispy_forms.helper import FormHelper
|
|
||||||
from crispy_forms.layout import Layout, Submit
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.db.models import CharField
|
|
||||||
from django_filters import FilterSet, CharFilter
|
|
||||||
|
|
||||||
|
|
||||||
class UserFilter(FilterSet):
|
|
||||||
class Meta:
|
|
||||||
model = User
|
|
||||||
fields = ['last_name', 'first_name', 'username', 'profile__section']
|
|
||||||
filter_overrides = {
|
|
||||||
CharField: {
|
|
||||||
'filter_class': CharFilter,
|
|
||||||
'extra': lambda f: {
|
|
||||||
'lookup_expr': 'icontains'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class UserFilterFormHelper(FormHelper):
|
|
||||||
form_method = 'GET'
|
|
||||||
layout = Layout(
|
|
||||||
'last_name',
|
|
||||||
'first_name',
|
|
||||||
'username',
|
|
||||||
'profile__section',
|
|
||||||
Submit('Submit', 'Apply Filter'),
|
|
||||||
)
|
|
|
@ -31,7 +31,11 @@ class ClubTable(tables.Table):
|
||||||
|
|
||||||
class UserTable(tables.Table):
|
class UserTable(tables.Table):
|
||||||
section = tables.Column(accessor='profile.section')
|
section = tables.Column(accessor='profile.section')
|
||||||
solde = tables.Column(accessor='note.balance')
|
|
||||||
|
balance = tables.Column(accessor='note.balance', verbose_name=_("Balance"))
|
||||||
|
|
||||||
|
def render_balance(self, value):
|
||||||
|
return pretty_money(value)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
attrs = {
|
attrs = {
|
||||||
|
@ -40,6 +44,10 @@ class UserTable(tables.Table):
|
||||||
template_name = 'django_tables2/bootstrap4.html'
|
template_name = 'django_tables2/bootstrap4.html'
|
||||||
fields = ('last_name', 'first_name', 'username', 'email')
|
fields = ('last_name', 'first_name', 'username', 'email')
|
||||||
model = User
|
model = User
|
||||||
|
row_attrs = {
|
||||||
|
'class': 'table-row',
|
||||||
|
'data-href': lambda record: record.pk
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class MembershipTable(tables.Table):
|
class MembershipTable(tables.Table):
|
||||||
|
|
|
@ -27,7 +27,6 @@ from note.tables import HistoryTable, AliasTable
|
||||||
from permission.backends import PermissionBackend
|
from permission.backends import PermissionBackend
|
||||||
from permission.views import ProtectQuerysetMixin
|
from permission.views import ProtectQuerysetMixin
|
||||||
|
|
||||||
from .filters import UserFilter, UserFilterFormHelper
|
|
||||||
from .forms import SignUpForm, ProfileForm, ClubForm, MembershipForm, CustomAuthenticationForm
|
from .forms import SignUpForm, ProfileForm, ClubForm, MembershipForm, CustomAuthenticationForm
|
||||||
from .models import Club, Membership
|
from .models import Club, Membership
|
||||||
from .tables import ClubTable, UserTable, MembershipTable
|
from .tables import ClubTable, UserTable, MembershipTable
|
||||||
|
@ -152,18 +151,29 @@ class UserListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
||||||
model = User
|
model = User
|
||||||
table_class = UserTable
|
table_class = UserTable
|
||||||
template_name = 'member/user_list.html'
|
template_name = 'member/user_list.html'
|
||||||
filter_class = UserFilter
|
|
||||||
formhelper_class = UserFilterFormHelper
|
|
||||||
|
|
||||||
def get_queryset(self, **kwargs):
|
def get_queryset(self, **kwargs):
|
||||||
qs = super().get_queryset()
|
qs = super().get_queryset()
|
||||||
self.filter = self.filter_class(self.request.GET, queryset=qs)
|
if "search" in self.request.GET:
|
||||||
self.filter.form.helper = self.formhelper_class()
|
pattern = self.request.GET["search"]
|
||||||
return self.filter.qs
|
|
||||||
|
if not pattern:
|
||||||
|
return qs.none()
|
||||||
|
|
||||||
|
qs = qs.filter(
|
||||||
|
Q(first_name__iregex=pattern)
|
||||||
|
| Q(last_name__iregex=pattern)
|
||||||
|
| Q(profile__section__iregex=pattern)
|
||||||
|
| Q(note__alias__name__iregex="^" + pattern)
|
||||||
|
| Q(note__alias__normalized_name__iregex=Alias.normalize("^" + pattern))
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
qs = qs.none()
|
||||||
|
|
||||||
|
return qs
|
||||||
|
|
||||||
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["filter"] = self.filter
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -949,7 +949,7 @@ msgid "search clubs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/member/club_list.html:12
|
#: templates/member/club_list.html:12
|
||||||
msgid "Créer un club"
|
msgid "Create club"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/member/club_list.html:19
|
#: templates/member/club_list.html:19
|
||||||
|
|
|
@ -952,8 +952,8 @@ msgid "search clubs"
|
||||||
msgstr "Chercher un club"
|
msgstr "Chercher un club"
|
||||||
|
|
||||||
#: templates/member/club_list.html:12
|
#: templates/member/club_list.html:12
|
||||||
msgid "Créer un club"
|
msgid "Create club"
|
||||||
msgstr ""
|
msgstr "Créer un club"
|
||||||
|
|
||||||
#: templates/member/club_list.html:19
|
#: templates/member/club_list.html:19
|
||||||
msgid "club listing "
|
msgid "club listing "
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</h4>
|
</h4>
|
||||||
<input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved();return(false);" id="search_field"/>
|
<input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved();return(false);" id="search_field"/>
|
||||||
<hr>
|
<hr>
|
||||||
<a class="btn btn-primary text-center my-4" href="{% url 'member:club_create' %}">{% trans "Créer un club" %}</a>
|
<a class="btn btn-primary text-center my-4" href="{% url 'member:club_create' %}">{% trans "Create club" %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
|
|
|
@ -2,28 +2,44 @@
|
||||||
{% load render_table from django_tables2 %}
|
{% load render_table from django_tables2 %}
|
||||||
{% load crispy_forms_tags%}
|
{% load crispy_forms_tags%}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<input id="searchbar" type="text" class="form-control" placeholder="Nom/prénom/note/section ...">
|
||||||
|
|
||||||
<a class="btn btn-primary" href="{% url 'member:signup' %}">New User</a>
|
<hr>
|
||||||
|
|
||||||
<div class="row">
|
<div id="user_table">
|
||||||
{% crispy filter.form filter.form.helper %}
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div id="replaceable-content" class="col-6">
|
|
||||||
{% render_table table %}
|
{% render_table table %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extrajavascript %}
|
{% block extrajavascript %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
let old_pattern = null;
|
||||||
|
let searchbar_obj = $("#searchbar");
|
||||||
|
|
||||||
|
function reloadTable() {
|
||||||
|
let pattern = searchbar_obj.val();
|
||||||
|
|
||||||
|
if (pattern === old_pattern || pattern === "")
|
||||||
|
return;
|
||||||
|
|
||||||
|
$("#user_table").load(location.href + "?search=" + pattern.replace(" ", "%20") + " #user_table", init);
|
||||||
|
|
||||||
$(document).ready(function($) {
|
|
||||||
$(".table-row").click(function() {
|
$(".table-row").click(function() {
|
||||||
window.document.location = $(this).data("href");
|
window.document.location = $(this).data("href");
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
searchbar_obj.keyup(reloadTable);
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
$(".table-row").click(function() {
|
||||||
|
window.document.location = $(this).data("href");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in New Issue