Skip to content
Snippets Groups Projects
Verified Commit d0a62cbc authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Add view for assigning child groups to groups

parent 7e153188
No related branches found
No related tags found
1 merge request!231Add view for assigning child groups to groups
Pipeline #1638 failed
from django_filters import FilterSet, CharFilter
from material import Layout, Row
class GroupFilter(FilterSet):
name = CharFilter(lookup_expr="icontains")
short_name = CharFilter(lookup_expr="icontains")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.layout = Layout(Row("name", "short_name"))
......@@ -276,3 +276,7 @@ class AnnouncementForm(ExtensibleForm):
class Meta:
model = Announcement
exclude = []
class ChildGroupsForm(forms.Form):
child_groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all())
......@@ -147,10 +147,26 @@ MENUS = {
"menu_generator.validators.is_superuser",
],
},
{
"name": _("Groups and child groups"),
"url": "groups_child_groups",
"icon": "group_add",
"validators": [
("aleksis.core.util.predicates.permission_validator", "core.assign_child_groups_to_groups")
],
},
],
},
],
"DATA_MANAGEMENT_MENU": [
{
"name": _("Assign child groups to groups"),
"url": "groups_child_groups",
"validators": [
("aleksis.core.util.predicates.permission_validator", "core.assign_child_groups_to_groups")
],
},
],
"DATA_MANAGEMENT_MENU": [],
"SCHOOL_MANAGEMENT_MENU": [
{"name": _("Edit school information"), "url": "edit_school_information", },
{"name": _("Edit school term"), "url": "edit_school_term", },
......
......@@ -255,6 +255,9 @@ class Group(ExtensibleModel):
ordering = ["short_name", "name"]
verbose_name = _("Group")
verbose_name_plural = _("Groups")
permissions = (
("assign_child_groups_to_groups", _("Can assign child groups to groups")),
)
icon_ = "group"
......
......@@ -83,6 +83,10 @@ edit_group_predicate = has_person & (
)
add_perm("core.edit_group", edit_group_predicate)
# Assign child groups to groups
assign_child_groups_to_groups_predicate = has_person & has_global_perm("core.assign_child_groups_to_groups")
add_perm("core.assign_child_groups_to_groups", assign_child_groups_to_groups_predicate)
# Edit school information
edit_school_information_predicate = has_person & has_global_perm("core.change_school")
add_perm("core.edit_school_information", edit_school_information_predicate)
......@@ -126,7 +130,7 @@ view_system_status_predicate = has_person & has_global_perm("core.view_system_st
add_perm("core.view_system_status", view_system_status_predicate)
# View people menu (persons + objects)
add_perm("core.view_people_menu", has_person & (view_persons_predicate | view_groups_predicate))
add_perm("core.view_people_menu", has_person & (view_persons_predicate | view_groups_predicate | link_persons_accounts_predicate | assign_child_groups_to_groups_predicate))
# View admin menu
view_admin_menu_predicate = has_person & (manage_data_predicate | manage_school_predicate | impersonate_predicate | view_system_status_predicate | view_announcements_predicate)
......
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n material_form %}
{% block browser_title %}{% blocktrans %}Assign child groups to groups{% endblocktrans %}{% endblock %}
{% block page_title %}
{% blocktrans %}Assign child groups to groups{% endblocktrans %}
{% endblock %}
{% block content %}
{% if not page %}
<div class="alert info">
<p>
<i class="material-icons left">info</i>
{% blocktrans %}
You can use this to assign child groups to groups. Please use the filters below to select groups you want to
change and click at "Next".
{% endblocktrans %}
</p>
</div>
<form method="get">
{% csrf_token %}
{% form form=filter.form %}{% endform %}
<button type="submit" class="btn green waves-effect waves-light">
<i class="material-icons left">refresh</i>
{% trans "Update selection" %}
</button>
<a href="{% url "groups_child_groups" %}" class="btn red waves-effect waves-light">
<i class="material-icons left">clear</i>
{% trans "Clear all filters" %}
</a>
</form>
<h5>{% trans "Currently selected groups" %}</h5>
{% for group in filter.qs %}
<div class="chip">
{{ group }}
</div>
{% endfor %}
{% if filter.qs %}
<p>
<form method="post">
{% csrf_token %}
<button class="btn btn-primary waves-effect waves-light" type="submit" name="page" value="1">
{% trans "Start assigning child groups for this groups" %}
<i class="material-icons right">arrow_forward</i>
</button>
</form>
</p>
{% else %}
<div class="alert warning">
<p>
<i class="material-icons left">warning</i>
{% blocktrans %}
Please select some groups in order to go on with assigning.
{% endblocktrans %}
</p>
</div>
{% endif %}
{% else %}
<form method="post">
<input type="hidden" name="old_page" value="{{ page.number }}">
<p class="flow-text">
{% trans "Current group:" %} {{ group }}
</p>
<div class="alert warning">
<p>
<i class="material-icons left">warning</i>
{% blocktrans %}
<strong>Please be careful!</strong><br/>
If you click on "Back" or "Next" the current group assignments are not saved.
If you click on save, you will overwrite all existing child group relations for this group with what you
selected on this page.
{% endblocktrans %}
</p>
</div>
<div class="row">
<p class="left">
{% if page.has_previous %}
<button class="btn grey waves-effect waves-light" name="page" value="{{ page.previous_page_number }}">
<i class="material-icons left">arrow_back</i>
{% trans "Back" %}
</button>
{% endif %}
{% if page.has_next %}
<button class="btn grey waves-effect waves-light" type="submit" name="page"
value="{{ page.next_page_number }}">
{% trans "Next" %}
<i class="material-icons right">arrow_forward</i>
</button>
{% endif %}
</p>
<p class="right">
<button class="btn green waves-effect waves-light" type="submit" name="save">
{% trans "Save" %}
<i class="material-icons left">save</i>
</button>
{% if page.has_next %}
<button class="btn green waves-effect waves-light" type="submit" name="save"
value="{{ page.next_page_number }}">
{% trans "Save and next" %}
<i class="material-icons left">save</i>
</button>
{% endif %}
</p>
</div>
{% csrf_token %}
{% include "components/chips.html" with form_field=form.child_groups %}
<p class="left">
{% if page.has_previous %}
<button class="btn grey waves-effect waves-light" name="page" value="{{ page.previous_page_number }}">
<i class="material-icons left">arrow_back</i>
{% trans "Back" %}
</button>
{% endif %}
{% if page.has_next %}
<button class="btn grey waves-effect waves-light" type="submit" name="page"
value="{{ page.next_page_number }}">
{% trans "Next" %}
<i class="material-icons right">arrow_forward</i>
</button>
{% endif %}
</p>
<p class="right">
<button class="btn green waves-effect waves-light" type="submit" name="save">
{% trans "Save" %}
<i class="material-icons left">save</i>
</button>
{% if page.has_next %}
<button class="btn green waves-effect waves-light" type="submit" name="save"
value="{{ page.next_page_number }}">
{% trans "Save and next" %}
<i class="material-icons left">save</i>
</button>
{% endif %}
</p>
</form>
{% endif %}
{% endblock %}
......@@ -32,6 +32,7 @@ urlpatterns = [
path("person/<int:id_>", views.person, name="person_by_id"),
path("person/<int:id_>/edit", views.edit_person, name="edit_person_by_id"),
path("groups", views.groups, name="groups"),
path("groups/child_groups/", views.groups_child_groups, name="groups_child_groups"),
path("group/create", views.edit_group, name="create_group"),
path("group/<int:id_>", views.group, name="group_by_id"),
path("group/<int:id_>/edit", views.edit_group, name="edit_group_by_id"),
......
......@@ -4,6 +4,7 @@ from typing import Optional
from django.apps import apps
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import PermissionDenied
from django.core.paginator import Paginator
from django.http import Http404, HttpRequest, HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.translation import gettext_lazy as _
......@@ -15,6 +16,7 @@ from haystack.query import SearchQuerySet
from haystack.views import SearchView
from rules.contrib.views import permission_required
from .filters import GroupFilter
from .forms import (
EditGroupForm,
EditPersonForm,
......@@ -22,6 +24,7 @@ from .forms import (
EditTermForm,
PersonsAccountsFormSet,
AnnouncementForm,
ChildGroupsForm,
)
from .models import Activity, Group, Notification, Person, School, DashboardWidget, Announcement
from .tables import GroupsTable, PersonsTable
......@@ -174,6 +177,43 @@ def persons_accounts(request: HttpRequest) -> HttpResponse:
return render(request, "core/persons_accounts.html", context)
@permission_required("core.assign_child_groups_to_groups")
def groups_child_groups(request: HttpRequest) -> HttpResponse:
""" Assign child groups to groups (for matching by MySQL importer) """
context = {}
# Apply filter
filter = GroupFilter(request.GET, queryset=Group.objects.all())
context["filter"] = filter
# Paginate
paginator = Paginator(filter.qs, 1)
page_number = request.POST.get("page", request.POST.get("old_page"))
if page_number:
page = paginator.get_page(page_number)
group = page[0]
if "save" in request.POST:
# Save
form = ChildGroupsForm(request.POST)
form.is_valid()
if "child_groups" in form.cleaned_data:
group.child_groups.set(form.cleaned_data["child_groups"])
group.save()
messages.success(request, _("The child groups were successfully saved."))
else:
# Init form
form = ChildGroupsForm(initial={"child_groups": group.child_groups.all()})
context["paginator"] = paginator
context["page"] = page
context["group"] = group
context["form"] = form
return render(request, "core/groups_child_groups.html", context)
def get_person_by_id(request: HttpRequest, id_:int):
return get_object_or_404(Person, id=id_)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment