diff --git a/core/templates/core/group_detail.jinja b/core/templates/core/group_detail.jinja
new file mode 100644
index 00000000..3e9dfe45
--- /dev/null
+++ b/core/templates/core/group_detail.jinja
@@ -0,0 +1,39 @@
+{% extends "core/base.jinja" %}
+{% from "core/macros.jinja" import select_all_checkbox %}
+
+{% block title %}
+ {% trans %}Group detail{% endtrans %}
+{% endblock title %}
+
+{% block content %}
+
{{ object }}
+ {% trans %}Back to list{% endtrans %}
+ {% if form.users_removed | length <= 0 %}
+ {% trans %}No user in this group{% endtrans %}
+ {% else %}
+
+ {% endif %}
+
+{% endblock content %}
\ No newline at end of file
diff --git a/core/templates/core/group_list.jinja b/core/templates/core/group_list.jinja
index 79bb5de4..e655335d 100644
--- a/core/templates/core/group_list.jinja
+++ b/core/templates/core/group_list.jinja
@@ -7,11 +7,25 @@
{% block content %}
{% trans %}Group list{% endtrans %}
{% trans %}New group{% endtrans %}
-
+
{% endblock %}
diff --git a/core/templates/core/macros.jinja b/core/templates/core/macros.jinja
index f713259a..36b9ed05 100644
--- a/core/templates/core/macros.jinja
+++ b/core/templates/core/macros.jinja
@@ -132,3 +132,18 @@
{% trans %}Next{% endtrans %}
{% endif %}
{% endmacro %}
+
+{% macro select_all_checkbox(form_id) %}
+
+
+
+{% endmacro %}
\ No newline at end of file
diff --git a/core/urls.py b/core/urls.py
index be18ff8e..6798a6bb 100644
--- a/core/urls.py
+++ b/core/urls.py
@@ -64,6 +64,11 @@ urlpatterns = [
GroupDeleteView.as_view(),
name="group_delete",
),
+ url(
+ r"^group/(?P[0-9]+)/detail$",
+ GroupTemplateView.as_view(),
+ name="group_detail",
+ ),
# User views
url(r"^user/$", UserListView.as_view(), name="user_list"),
url(
diff --git a/core/views/__init__.py b/core/views/__init__.py
index 2d764237..c4972bd0 100644
--- a/core/views/__init__.py
+++ b/core/views/__init__.py
@@ -39,6 +39,9 @@ from django.core.exceptions import (
ImproperlyConfigured,
)
from django.views.generic.base import View
+from django.views.generic.edit import FormView
+from django.views.generic.detail import SingleObjectMixin
+from django.utils.functional import cached_property
from django.db.models import Count
from core.models import Group
@@ -275,6 +278,30 @@ class QuickNotifMixin:
return kwargs
+class DetailFormView(SingleObjectMixin, FormView):
+ """
+ Class that allow both a detail view and a form view
+ """
+
+ def get_object(self):
+ """
+ Get current group from id in url
+ """
+ return self.cached_object
+
+ @cached_property
+ def cached_object(self):
+ """
+ Optimisation on group retrieval
+ """
+ return super(DetailFormView, self).get_object()
+
+ def get_context_data(self, *args, **kwargs):
+ kwargs = super(DetailFormView, self).get_context_data()
+ kwargs["object"] = self.get_object()
+ return kwargs
+
+
from .user import *
from .page import *
from .files import *
diff --git a/core/views/group.py b/core/views/group.py
index 29864dbc..059c5dc5 100644
--- a/core/views/group.py
+++ b/core/views/group.py
@@ -22,24 +22,87 @@
#
#
+"""
+ This module contains views to manage Groups
+"""
+
from django.views.generic.edit import UpdateView, CreateView, DeleteView
from django.views.generic import ListView
+from django.views.generic.edit import FormView
from django.core.urlresolvers import reverse_lazy
+from django.shortcuts import get_object_or_404
+from django.utils.translation import ugettext_lazy as _
+from django import forms
-from core.models import RealGroup
-from core.views import CanEditMixin
+from ajax_select.fields import AutoCompleteSelectMultipleField
+
+from core.models import RealGroup, User
+from core.views import CanEditMixin, DetailFormView
+
+# Forms
+
+
+class EditMembersForm(forms.Form):
+ """
+ Add and remove members from a Group
+ """
+
+ def __init__(self, *args, **kwargs):
+ self.current_users = kwargs.pop("users", [])
+ super(EditMembersForm, self).__init__(*args, **kwargs)
+ self.fields["users_removed"] = forms.ModelMultipleChoiceField(
+ User.objects.filter(id__in=self.current_users).all(),
+ label=_("Users to remove from group"),
+ required=False,
+ widget=forms.CheckboxSelectMultiple,
+ )
+
+ users_added = AutoCompleteSelectMultipleField(
+ "users",
+ label=_("Users to add to group"),
+ help_text=_("Search users to add (one or more)."),
+ required=False,
+ )
+
+ def clean_users_added(self):
+ """
+ Check that the user is not trying to add an user already in the group
+ """
+ cleaned_data = super(EditMembersForm, self).clean()
+ users_added = cleaned_data.get("users_added", None)
+ if not users_added:
+ return users_added
+
+ current_users = [
+ str(id_) for id_ in self.current_users.values_list("id", flat=True)
+ ]
+ for user in users_added:
+ if user in current_users:
+ raise forms.ValidationError(
+ _("You can not add the same user twice"), code="invalid"
+ )
+
+ return users_added
+
+
+# Views
class GroupListView(CanEditMixin, ListView):
"""
- Displays the group list
+ Displays the Group list
"""
model = RealGroup
+ ordering = ["name"]
template_name = "core/group_list.jinja"
class GroupEditView(CanEditMixin, UpdateView):
+ """
+ Edit infos of a Group
+ """
+
model = RealGroup
pk_url_kwarg = "group_id"
template_name = "core/group_edit.jinja"
@@ -47,12 +110,55 @@ class GroupEditView(CanEditMixin, UpdateView):
class GroupCreateView(CanEditMixin, CreateView):
+ """
+ Add a new Group
+ """
+
model = RealGroup
template_name = "core/group_edit.jinja"
fields = ["name", "description"]
+class GroupTemplateView(CanEditMixin, DetailFormView):
+ """
+ Display all users in a given Group
+ Allow adding and removing users from it
+ """
+
+ model = RealGroup
+ form_class = EditMembersForm
+ pk_url_kwarg = "group_id"
+ template_name = "core/group_detail.jinja"
+
+ def form_valid(self, form):
+ resp = super(GroupTemplateView, self).form_valid(form)
+
+ data = form.clean()
+ group = self.get_object()
+ for user in data["users_removed"]:
+ group.users.remove(user)
+ for user in data["users_added"]:
+ group.users.add(user)
+ group.save()
+
+ return resp
+
+ def get_success_url(self):
+ return reverse_lazy(
+ "core:group_detail", kwargs={"group_id": self.get_object().id}
+ )
+
+ def get_form_kwargs(self):
+ kwargs = super(GroupTemplateView, self).get_form_kwargs()
+ kwargs["users"] = self.get_object().users.all()
+ return kwargs
+
+
class GroupDeleteView(CanEditMixin, DeleteView):
+ """
+ Delete a Group
+ """
+
model = RealGroup
pk_url_kwarg = "group_id"
template_name = "core/delete_confirm.jinja"
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index f880d485..a62e1c94 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-03-19 17:16+0100\n"
+"POT-Creation-Date: 2019-04-22 14:57+0200\n"
"PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Skia \n"
"Language-Team: AE info \n"
@@ -361,7 +361,8 @@ msgstr "Compte en banque : "
#: com/templates/com/weekmail.jinja:62 core/templates/core/file_detail.jinja:25
#: core/templates/core/file_detail.jinja:62
#: core/templates/core/file_moderation.jinja:24
-#: core/templates/core/group_list.jinja:13 core/templates/core/macros.jinja:93
+#: core/templates/core/group_detail.jinja:26
+#: core/templates/core/group_list.jinja:25 core/templates/core/macros.jinja:93
#: core/templates/core/macros.jinja:112 core/templates/core/page_prop.jinja:14
#: core/templates/core/user_account_detail.jinja:38
#: core/templates/core/user_detail.jinja:178
@@ -417,7 +418,8 @@ msgstr "Nouveau compte club"
#: com/templates/com/poster_list.jinja:45
#: com/templates/com/screen_list.jinja:26 com/templates/com/weekmail.jinja:32
#: com/templates/com/weekmail.jinja:61 core/templates/core/file.jinja:38
-#: core/templates/core/page.jinja:35 core/templates/core/poster_list.jinja:40
+#: core/templates/core/group_list.jinja:24 core/templates/core/page.jinja:35
+#: core/templates/core/poster_list.jinja:40
#: core/templates/core/user_tools.jinja:42 core/views/user.py:237
#: counter/templates/counter/cash_summary_list.jinja:53
#: counter/templates/counter/counter_list.jinja:17
@@ -1031,6 +1033,7 @@ msgstr "Rôle"
#: club/templates/club/club_members.jinja:10
#: club/templates/club/club_old_members.jinja:10
+#: core/templates/core/group_list.jinja:15
#: core/templates/core/user_clubs.jinja:17
#: core/templates/core/user_clubs.jinja:43
msgid "Description"
@@ -2572,10 +2575,19 @@ msgstr "Modération des fichiers"
msgid "Full name: "
msgstr "Nom complet : "
+#: core/templates/core/group_detail.jinja:5
+msgid "Group detail"
+msgstr "Détail du groupe"
+
+#: core/templates/core/group_detail.jinja:10
#: core/templates/core/group_edit.jinja:4
msgid "Back to list"
msgstr "Retour à la liste"
+#: core/templates/core/group_detail.jinja:12
+msgid "No user in this group"
+msgstr "Aucun utilisateur dans ce groupe"
+
#: core/templates/core/group_edit.jinja:5
msgid "Edit group"
msgstr "Éditer le groupe"
@@ -2595,6 +2607,14 @@ msgstr "Liste des groupes"
msgid "New group"
msgstr "Nouveau groupe"
+#: core/templates/core/group_list.jinja:13
+msgid "ID"
+msgstr "ID"
+
+#: core/templates/core/group_list.jinja:14
+msgid "Group"
+msgstr "Groupe"
+
#: core/templates/core/login.jinja:10
msgid "Your username and password didn't match. Please try again."
msgstr ""
@@ -2660,6 +2680,14 @@ msgstr "actuel"
msgid "Next"
msgstr "Suivant"
+#: core/templates/core/macros.jinja:147
+msgid "Select All"
+msgstr "Tout sélectionner"
+
+#: core/templates/core/macros.jinja:148
+msgid "Unselect All"
+msgstr "Tout désélectionner"
+
#: core/templates/core/macros_pages.jinja:4
#, python-format
msgid "You're seeing the history of page \"%(page_name)s\""
@@ -3489,6 +3517,22 @@ msgstr "groupe d'édition"
msgid "view groups"
msgstr "groupe de vue"
+#: core/views/group.py:55
+msgid "Users to remove from group"
+msgstr "Utilisateurs à retirer du groupe"
+
+#: core/views/group.py:62
+msgid "Users to add to group"
+msgstr "Utilisateurs à ajouter au groupe"
+
+#: core/views/group.py:63
+msgid "Search users to add (one or more)."
+msgstr "Recherche les utilisateurs à ajouter (un ou plus)."
+
+#: core/views/group.py:82
+msgid "You can not add the same user twice"
+msgstr "Vous ne pouvez pas ajouter deux fois le même utilisateur"
+
#: core/views/user.py:223 trombi/templates/trombi/export.jinja:25
#: trombi/templates/trombi/user_profile.jinja:11
msgid "Pictures"