Skip to content
Snippets Groups Projects
Commit b438cbca authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Merge branch '69-add-support-for-assinging-class-roles' into 'master'

Resolve "Add support for assinging group roles"

Closes #69

See merge request !131
parents 8bfc0ca7 51bbefe6
Branches
Tags
1 merge request!131Resolve "Add support for assinging group roles"
Pipeline #6050 passed
Showing
with 733 additions and 9 deletions
......@@ -5,16 +5,24 @@ from django.core.exceptions import ValidationError
from django.db.models import Count, Q
from django.utils.translation import gettext_lazy as _
from django_select2.forms import Select2Widget
from django_select2.forms import ModelSelect2MultipleWidget, ModelSelect2Widget, Select2Widget
from guardian.shortcuts import get_objects_for_user
from material import Fieldset, Layout, Row
from aleksis.apps.chronos.managers import TimetableType
from aleksis.apps.chronos.models import TimePeriod
from aleksis.core.models import Group, Person
from aleksis.core.util.core_helpers import get_site_preferences
from aleksis.core.util.predicates import check_global_permission
from .models import ExcuseType, ExtraMark, LessonDocumentation, PersonalNote
from .models import (
ExcuseType,
ExtraMark,
GroupRole,
GroupRoleAssignment,
LessonDocumentation,
PersonalNote,
)
class LessonDocumentationForm(forms.ModelForm):
......@@ -160,3 +168,89 @@ class ExcuseTypeForm(forms.ModelForm):
class Meta:
model = ExcuseType
fields = ["short_name", "name"]
class GroupRoleForm(forms.ModelForm):
layout = Layout("name", "icon", "colour")
class Meta:
model = GroupRole
fields = ["name", "icon", "colour"]
class AssignGroupRoleForm(forms.ModelForm):
layout_base = ["groups", "person", "role", Row("date_start", "date_end")]
groups = forms.ModelMultipleChoiceField(
label=_("Group"),
required=True,
queryset=Group.objects.all(),
widget=ModelSelect2MultipleWidget(
model=Group,
search_fields=["name__icontains", "short_name__icontains"],
attrs={"data-minimum-input-length": 0, "class": "browser-default",},
),
)
person = forms.ModelChoiceField(
label=_("Person"),
required=True,
queryset=Person.objects.all(),
widget=ModelSelect2Widget(
model=Person,
search_fields=[
"first_name__icontains",
"last_name__icontains",
"short_name__icontains",
],
attrs={"data-minimum-input-length": 0, "class": "browser-default"},
),
)
def __init__(self, request, *args, **kwargs):
self.request = request
initial = kwargs.get("initial", {})
# Build layout with or without groups field
base_layout = self.layout_base[:]
if "groups" in initial:
base_layout.remove("groups")
self.layout = Layout(*base_layout)
super().__init__(*args, **kwargs)
if "groups" in initial:
self.fields["groups"].required = False
# Filter persons and groups by permissions
if not self.request.user.has_perm("alsijil.assign_grouprole"): # Global permission
persons = Person.objects
if initial.get("groups"):
persons = persons.filter(member_of__in=initial["groups"])
if get_site_preferences()["alsijil__group_owners_can_assign_roles_to_parents"]:
persons = persons.filter(
Q(member_of__owners=self.request.user.person)
| Q(children__member_of__owners=self.request.user.person)
)
else:
persons = persons.filter(member_of__owners=self.request.user.person)
self.fields["person"].queryset = persons
if "groups" not in initial:
groups = Group.objects.for_current_school_term_or_all().filter(
owners=self.request.user.person
)
self.fields["groups"].queryset = groups
def clean_groups(self):
"""Ensure that only permitted groups are used."""
return self.initial["groups"] if "groups" in self.initial else self.cleaned_data["groups"]
class Meta:
model = GroupRoleAssignment
fields = ["groups", "person", "role", "date_start", "date_end"]
class GroupRoleAssignmentEditForm(forms.ModelForm):
class Meta:
model = GroupRoleAssignment
fields = ["date_start", "date_end"]
from datetime import date, datetime
from typing import Optional, Sequence, Union
from django.db.models import QuerySet
from django.db.models.query import Prefetch
from django.db.models.query_utils import Q
from calendarweek import CalendarWeek
from aleksis.apps.chronos.managers import DateRangeQuerySetMixin
from aleksis.core.managers import CurrentSiteManagerWithoutMigrations
......@@ -42,3 +49,51 @@ class LessonDocumentationQuerySet(QuerySet):
def not_empty(self):
"""Get all not empty lesson documentations."""
return self.filter(~Q(topic="") | ~Q(group_note="") | ~Q(homework=""))
class GroupRoleManager(CurrentSiteManagerWithoutMigrations):
pass
class GroupRoleQuerySet(QuerySet):
def with_assignments(
self, time_ref: Union[date, CalendarWeek], groups: Sequence["Group"]
) -> QuerySet:
from aleksis.apps.alsijil.models import GroupRoleAssignment
if isinstance(time_ref, CalendarWeek):
qs = GroupRoleAssignment.objects.in_week(time_ref)
else:
qs = GroupRoleAssignment.objects.on_day(time_ref)
qs = qs.for_groups(groups).distinct()
return self.prefetch_related(Prefetch("assignments", queryset=qs,))
class GroupRoleAssignmentManager(CurrentSiteManagerWithoutMigrations):
pass
class GroupRoleAssignmentQuerySet(DateRangeQuerySetMixin, QuerySet):
def within_dates(self, start: date, end: date):
"""Filter for all role assignments within a date range."""
return self.filter(
Q(date_start__lte=end) & (Q(date_end__gte=start) | Q(date_end__isnull=True))
)
def at_time(self, when: Optional[datetime] = None):
"""Filter for role assignments assigned at a certain point in time."""
now = when or datetime.now()
return self.on_day(now.date())
def for_groups(self, groups: Sequence["Group"]):
"""Filter all role assignments for a sequence of groups."""
qs = self
for group in groups:
qs = qs.for_group(group)
return qs
def for_group(self, group: "Group"):
"""Filter all role assignments for a group."""
return self.filter(Q(groups=group) | Q(groups__child_groups=group))
......@@ -67,6 +67,17 @@ MENUS = {
),
],
},
{
"name": _("Assign group role"),
"url": "assign_group_role_multiple",
"icon": "assignment_ind",
"validators": [
(
"aleksis.core.util.predicates.permission_validator",
"alsijil.assign_grouprole_for_multiple",
),
],
},
{
"name": _("Excuse types"),
"url": "excuse_types",
......@@ -89,6 +100,17 @@ MENUS = {
),
],
},
{
"name": _("Manage group roles"),
"url": "group_roles",
"icon": "assignment_ind",
"validators": [
(
"aleksis.core.util.predicates.permission_validator",
"alsijil.view_grouproles",
),
],
},
],
}
]
......
# Generated by Django 3.1.5 on 2021-02-07 15:21
import aleksis.apps.chronos.managers
from aleksis.core.util.model_helpers import ICONS
import colorfield.fields
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('core', '0009_default_dashboard'),
('sites', '0002_alter_domain_unique'),
('alsijil', '0008_global_permissions'),
]
operations = [
migrations.CreateModel(
name='GroupRole',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('extended_data', models.JSONField(default=dict, editable=False)),
('name', models.CharField(max_length=255, verbose_name='Name')),
('icon', models.CharField(blank=True, choices=(lambda: ICONS)(), max_length=50, verbose_name='Icon')),
('colour', colorfield.fields.ColorField(blank=True, default='', max_length=18, verbose_name='Colour')),
('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.site')),
],
options={
'verbose_name': 'Group role',
'verbose_name_plural': 'Group roles',
},
),
migrations.CreateModel(
name='GroupRoleAssignment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('extended_data', models.JSONField(default=dict, editable=False)),
('date_start', models.DateField(verbose_name='Start date')),
('date_end', models.DateField(blank=True, help_text='Can be left empty if end date is not clear yet', null=True, verbose_name='End date')),
('groups', models.ManyToManyField(related_name='group_roles', to='core.Group', verbose_name='Groups')),
('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='group_roles', to='core.person', verbose_name='Assigned person')),
('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='assignments', to='alsijil.grouprole', verbose_name='Group role')),
('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.site')),
],
options={
'verbose_name': 'Group role assignment',
'verbose_name_plural': 'Group role assignments',
},
bases=(aleksis.apps.chronos.managers.GroupPropertiesMixin, models.Model),
),
]
......@@ -4,6 +4,7 @@ from django.utils.formats import date_format
from django.utils.translation import gettext_lazy as _
from calendarweek import CalendarWeek
from colorfield.fields import ColorField
from aleksis.apps.alsijil.data_checks import (
ExcusesWithoutAbsences,
......@@ -13,16 +14,22 @@ from aleksis.apps.alsijil.data_checks import (
PersonalNoteOnHolidaysDataCheck,
)
from aleksis.apps.alsijil.managers import (
GroupRoleAssignmentManager,
GroupRoleAssignmentQuerySet,
GroupRoleManager,
GroupRoleQuerySet,
LessonDocumentationManager,
LessonDocumentationQuerySet,
PersonalNoteManager,
PersonalNoteQuerySet,
)
from aleksis.apps.chronos.managers import GroupPropertiesMixin
from aleksis.apps.chronos.mixins import WeekRelatedMixin
from aleksis.apps.chronos.models import LessonPeriod
from aleksis.apps.chronos.util.date import get_current_year
from aleksis.core.mixins import ExtensibleModel
from aleksis.core.util.core_helpers import get_site_preferences
from aleksis.core.util.model_helpers import ICONS
def isidentifier(value: str) -> bool:
......@@ -239,6 +246,63 @@ class ExtraMark(ExtensibleModel):
verbose_name_plural = _("Extra marks")
class GroupRole(ExtensibleModel):
objects = GroupRoleManager.from_queryset(GroupRoleQuerySet)()
name = models.CharField(max_length=255, verbose_name=_("Name"))
icon = models.CharField(max_length=50, blank=True, choices=ICONS, verbose_name=_("Icon"))
colour = ColorField(blank=True, verbose_name=_("Colour"))
def __str__(self):
return self.name
class Meta:
verbose_name = _("Group role")
verbose_name_plural = _("Group roles")
class GroupRoleAssignment(GroupPropertiesMixin, ExtensibleModel):
objects = GroupRoleAssignmentManager.from_queryset(GroupRoleAssignmentQuerySet)()
role = models.ForeignKey(
GroupRole,
on_delete=models.CASCADE,
related_name="assignments",
verbose_name=_("Group role"),
)
person = models.ForeignKey(
"core.Person",
on_delete=models.CASCADE,
related_name="group_roles",
verbose_name=_("Assigned person"),
)
groups = models.ManyToManyField(
"core.Group", related_name="group_roles", verbose_name=_("Groups"),
)
date_start = models.DateField(verbose_name=_("Start date"))
date_end = models.DateField(
blank=True,
null=True,
verbose_name=_("End date"),
help_text=_("Can be left empty if end date is not clear yet"),
)
def __str__(self):
date_end = date_format(self.date_end) if self.date_end else "?"
return f"{self.role}: {self.person}, {date_format(self.date_start)}{date_end}"
@property
def date_range(self) -> str:
if not self.date_end:
return f"{date_format(self.date_start)}–?"
else:
return f"{date_format(self.date_start)}{date_format(self.date_end)}"
class Meta:
verbose_name = _("Group role assignment")
verbose_name_plural = _("Group role assignments")
class AlsijilGlobalPermissions(ExtensibleModel):
class Meta:
managed = False
......
......@@ -3,7 +3,7 @@ from django.utils.translation import gettext as _
from dynamic_preferences.preferences import Section
from dynamic_preferences.types import BooleanPreference
from aleksis.core.registries import site_preferences_registry
from aleksis.core.registries import person_preferences_registry, site_preferences_registry
alsijil = Section("alsijil", verbose_name=_("Class register"))
......@@ -74,3 +74,30 @@ class AllowEntriesInHolidays(BooleanPreference):
name = "allow_entries_in_holidays"
default = False
verbose_name = _("Allow teachers to add data for lessons in holidays")
@site_preferences_registry.register
class GroupOwnersCanAssignRolesToParents(BooleanPreference):
section = alsijil
name = "group_owners_can_assign_roles_to_parents"
default = False
verbose_name = _(
"Allow group owners to assign group roles to the parents of the group's members"
)
@person_preferences_registry.register
class ShowGroupRolesInWeekView(BooleanPreference):
section = alsijil
name = "group_roles_in_week_view"
default = True
verbose_name = _("Show assigned group roles in week view")
help_text = _("Only week view of groups")
@person_preferences_registry.register
class ShowGroupRolesInLessonView(BooleanPreference):
section = alsijil
name = "group_roles_in_lesson_view"
default = True
verbose_name = _("Show assigned group roles in lesson view")
......@@ -14,11 +14,13 @@ from .util.predicates import (
has_personal_note_group_perm,
is_group_member,
is_group_owner,
is_group_role_assignment_group_owner,
is_lesson_parent_group_owner,
is_lesson_participant,
is_lesson_teacher,
is_none,
is_own_personal_note,
is_owner_of_any_group,
is_person_group_owner,
is_person_primary_group_owner,
is_personal_note_lesson_parent_group_owner,
......@@ -218,3 +220,56 @@ add_perm("alsijil.edit_extramark", edit_extramark_predicate)
# Delete extra mark
delete_extramark_predicate = view_extramarks_predicate & has_global_perm("alsijil.delete_extramark")
add_perm("alsijil.delete_extramark", delete_extramark_predicate)
# View group role list
view_group_roles_predicate = has_global_perm("alsijil.view_grouprole")
add_perm("alsijil.view_grouproles", view_group_roles_predicate)
# Add group role
add_group_role_predicate = view_group_roles_predicate & has_global_perm("alsijil.add_grouprole")
add_perm("alsijil.add_grouprole", add_group_role_predicate)
# Edit group role
edit_group_role_predicate = view_group_roles_predicate & has_global_perm("alsijil.change_grouprole")
add_perm("alsijil.edit_grouprole", edit_group_role_predicate)
# Delete group role
delete_group_role_predicate = view_group_roles_predicate & has_global_perm(
"alsijil.delete_grouprole"
)
add_perm("alsijil.delete_grouprole", delete_group_role_predicate)
view_assigned_group_roles_predicate = (
is_group_owner
| is_lesson_teacher
| is_lesson_parent_group_owner
| has_global_perm("alsjil.assign_grouprole")
| has_object_perm("alsijil.assign_grouprole")
)
add_perm("alsijil.view_assigned_grouproles", view_assigned_group_roles_predicate)
assign_group_role_person_predicate = is_person_group_owner | has_global_perm(
"alsjil.assign_grouprole"
)
add_perm("alsijil.assign_grouprole_to_person", assign_group_role_person_predicate)
assign_group_role_for_multiple_predicate = is_owner_of_any_group | has_global_perm(
"alsjil.assign_grouprole"
)
add_perm("alsijil.assign_grouprole_for_multiple", assign_group_role_for_multiple_predicate)
assign_group_role_group_predicate = view_assigned_group_roles_predicate
add_perm("alsijil.assign_grouprole_for_group", assign_group_role_group_predicate)
edit_group_role_assignment_predicate = (
has_global_perm("alsjil.assign_grouprole") | is_group_role_assignment_group_owner
)
add_perm("alsijil.edit_grouproleassignment", edit_group_role_assignment_predicate)
stop_group_role_assignment_predicate = edit_group_role_assignment_predicate
add_perm("alsijil.stop_grouproleassignment", stop_group_role_assignment_predicate)
delete_group_role_assignment_predicate = (
has_global_perm("alsjil.assign_grouprole") | is_group_role_assignment_group_owner
)
add_perm("alsijil.delete_grouproleassignment", delete_group_role_assignment_predicate)
from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _
import django_tables2 as tables
......@@ -48,3 +49,32 @@ class ExcuseTypeTable(tables.Table):
self.columns.hide("edit")
if not request.user.has_perm("alsijil.delete_excusetype"):
self.columns.hide("delete")
class GroupRoleTable(tables.Table):
class Meta:
attrs = {"class": "highlight"}
name = tables.LinkColumn("edit_excuse_type", args=[A("id")])
edit = tables.LinkColumn(
"edit_group_role",
args=[A("id")],
text=_("Edit"),
attrs={"a": {"class": "btn-flat waves-effect waves-orange orange-text"}},
)
delete = tables.LinkColumn(
"delete_group_role",
args=[A("id")],
text=_("Delete"),
attrs={"a": {"class": "btn-flat waves-effect waves-red red-text"}},
)
def render_name(self, value, record):
context = dict(role=record)
return render_to_string("alsijil/group_role/chip.html", context)
def before_render(self, request):
if not request.user.has_perm("alsijil.edit_grouprole"):
self.columns.hide("edit")
if not request.user.has_perm("alsijil.delete_grouprole"):
self.columns.hide("delete")
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n static %}
{% load i18n static rules %}
{% block browser_title %}{% blocktrans %}My groups{% endblocktrans %}{% endblock %}
......@@ -38,6 +38,13 @@
<i class="material-icons left">view_week</i>
{% trans "Week view" %}
</a>
{% has_perm "alsijil.view_assigned_grouproles" user group as can_view_assigned_group_roles %}
{% if can_view_assigned_group_roles %}
<a class="btn primary waves-effect waves-light" href="{% url 'assigned_group_roles' group.pk %}">
<i class="material-icons left">assignment_ind</i>
{% trans "Roles" %}
</a>
{% endif %}
<a class="btn primary waves-effect waves-light" href="{% url "full_register_group" group.pk %}"
target="_blank">
<i class="material-icons left">print</i>
......@@ -75,6 +82,15 @@
{% trans "Week view" %}
</a>
</p>
{% has_perm "alsijil.view_assigned_grouproles" user group as can_view_assigned_group_roles %}
{% if can_view_assigned_group_roles %}
<p>
<a class="btn primary waves-effect waves-light" href="{% url 'assigned_group_roles' group.pk %}">
<i class="material-icons left">assignment_ind</i>
{% trans "Roles" %}
</a>
</p>
{% endif %}
<p>
<a class="btn primary waves-effect waves-light" href="{% url "full_register_group" group.pk %}"
target="_blank">
......
......@@ -111,6 +111,11 @@
<a href="#previous-lesson">{% trans "Previous lesson" %}</a>
</li>
{% endif %}
{% if group_roles %}
<li class="tab">
<a href="#group-roles">{% trans "Group roles" %}</a>
</li>
{% endif %}
<li class="tab">
<a href="#version-history">{% trans "Change history" %}</a>
</li>
......@@ -257,7 +262,13 @@
{% if can_edit_lesson_personalnote %}
<tr>
{{ form.id }}
<td>{{ form.person_name }}{{ form.person_name.value }}</td>
<td>{{ form.person_name }}{{ form.person_name.value }}
<p>
{% for assignment in form.instance.person.group_roles.all %}
{% include "alsijil/group_role/chip.html" with role=assignment.role %}
{% endfor %}
</p>
</td>
<td class="center-align">
<label>
{{ form.absent }}
......@@ -310,7 +321,13 @@
</tr>
{% else %}
<tr>
<td>{{ form.person_name.value }}</td>
<td>{{ form.person_name.value }}
<p>
{% for assignment in form.instance.person.group_roles.all %}
{% include "alsijil/group_role/chip.html" with role=assignment.role %}
{% endfor %}
</p>
</td>
<td><i class="material-icons center">{{ form.absent.value|yesno:"check,clear" }}</i></td>
<td>
<i class="material-icons center">{{ form.late.value|yesno:"check,clear" }}</i>
......@@ -338,6 +355,12 @@
</div>
{% endif %}
{% if group_roles %}
<div class="col s12" id="group-roles">
{% include "alsijil/group_role/partials/assigned_roles.html" with roles=group_roles group=lesson_period.lesson.groups.first back_url=back_url %}
</div>
{% endif %}
{% if can_view_lesson_documentation %}
<div class="col s12" id="version-history">
<div class="card">
......
......@@ -64,12 +64,17 @@
<div class="row">
<div class="col s12">
<ul class="tabs">
<li class="tab col s6">
<li class="tab col">
<a class="active" href="#week-overview">{% trans "Lesson documentations" %}</a>
</li>
<li class="tab col s6">
<a class="active" href="#personal-notes">{% trans "Personal notes" %}</a>
<li class="tab col">
<a href="#personal-notes">{% trans "Personal notes" %}</a>
</li>
{% if group_roles %}
<li class="tab col">
<a href="#group-roles">{% trans "Group roles" %}</a>
</li>
{% endif %}
</ul>
</div>
<div class="col s12" id="week-overview">
......@@ -283,6 +288,11 @@
</a>
{% endif %}
</h5>
<p>
{% for assignment in person.person.group_roles.all %}
{% include "alsijil/group_role/chip.html" with role=assignment.role small=assignment.date_range %}
{% endfor %}
</p>
<p class="card-text">
{% trans "Absent" %}: {{ person.person.absences_count }}
({{ person.person.unexcused_count }} {% trans "unexcused" %})
......@@ -315,6 +325,11 @@
</div>
</div>
</div>
{% if group_roles %}
<div class="col s12" id="group-roles">
{% include "alsijil/group_role/partials/assigned_roles.html" with roles=group_roles group=group back_url=back_url %}
</div>
{% endif %}
</div>
{% else %}
<div class="card red darken-1">
......
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n rules any_js material_form %}
{% block browser_title %}
{% if group %}
{% blocktrans with group=group.name %}Assign group role for {{ group }}{% endblocktrans %}
{% else %}
{% trans "Assign group role" %}
{% endif %}
{% endblock %}
{% block page_title %}
{% if group %}
{% blocktrans with group=group.name %}Assign group role for {{ group }}{% endblocktrans %}
{% else %}
{% trans "Assign group role" %}
{% endif %}
{% endblock %}
{% block extra_head %}
{{ form.media.css }}
{% include_css "select2-materialize" %}
{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{% form form=form %}{% endform %}
<button type="submit" class="btn green waves-effect waves-light">
<i class="material-icons left">assignment_ind</i>
{% trans "Assign" %}
</button>
</form>
{% include_js "select2-materialize" %}
{{ form.media.js }}
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n rules any_js material_form static %}
{% load render_table from django_tables2 %}
{% block browser_title %}
{% blocktrans with group=object.name %}Group roles for {{ group }}{% endblocktrans %}
{% endblock %}
{% block page_title %}
{% blocktrans with group=object.name %}Group roles for {{ group }}{% endblocktrans %}
{% endblock %}
{% block extra_head %}
{{ block.super }}
<link rel="stylesheet" href="{% static "css/alsijil/alsijil.css" %}"/>
{% endblock %}
{% block content %}
{% url "assigned_group_roles" object.pk as back_url %}
<p>
{% has_perm "alsijil.view_my_groups" user as can_view_group_overview %}
{% if can_view_group_overview %}
<a class="btn waves-effect waves-light" href="{% url "my_groups" %}">
<i class="material-icons left">arrow_back</i>
{% trans "Back to my groups" %}
</a>
{% endif %}
{% has_perm "alsijil.assign_grouprole_for_group" user object as can_assign_group_role %}
{% if can_assign_group_role %}
<a class="btn green waves-effect waves-light" href="{% url "assign_group_role" object.pk %}">
<i class="material-icons left">assignment_ind</i>
{% trans "Assign a role to a person" %}
</a>
{% endif %}
</p>
<div class="row">
<div class="col s12">
<ul class="tabs">
<li class="tab">
<a class="active" href="#current">{% trans "Current roles" %} ({{ today|date:"SHORT_DATE_FORMAT" }})</a>
</li>
<li class="tab">
<a href="#all">{% trans "All assignments" %}</a>
</li>
</ul>
</div>
<div id="current" class="col s12">
{% include "alsijil/group_role/partials/assigned_roles.html" with roles=roles group=object back_url=back_url %}
</div>
<div class="col s12 " id="all">
<table class="responsive-table">
<thead>
<tr>
<th class="chip-height">{% trans "Group role" %}</th>
<th>{% trans "Person" %}</th>
<th>{% trans "Start date" %}</th>
<th>{% trans "End date" %}</th>
<th>{% trans "Actions" %}</th>
</tr>
</thead>
{% for assignment in assignments %}
<tr>
<td>
{% include "alsijil/group_role/chip.html" with role=assignment.role %}
</td>
<td>
{{ assignment.person }}
</td>
<td>{{ assignment.date_start }}</td>
<td>{{ assignment.date_end|default:"–" }}</td>
<td>
<a class="btn waves-effect waves-light dropdown-trigger" href="#"
data-target="dropdown-{{ assignment.pk }}-d2">
<i class="material-icons left">list</i>
{% trans "Actions" %}
</a>
{% include "alsijil/group_role/partials/assignment_options.html" with assignment=assignment back_url=back_url suffix="-d2" %}
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
{% endblock %}
{# -*- engine:django -*- #}
<div class="chip white-text" style="background-color: {{ role.colour|default:"black" }};">
<i class="material-icons left">{{ role.icon|default:"assignment_ind" }}</i>
{{ role.name }}
{% if small %}
<small>({{ small }})</small>
{% endif %}
</div>
\ No newline at end of file
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load material_form i18n %}
{% block browser_title %}{% blocktrans %}Create group role{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Create group role{% endblocktrans %}{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{% form form=form %}{% endform %}
{% include "core/partials/save_button.html" %}
</form>
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load material_form i18n %}
{% block browser_title %}{% blocktrans %}Edit group role{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Edit group role{% endblocktrans %}{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{% form form=form %}{% endform %}
{% include "core/partials/save_button.html" %}
</form>
{{ form.media.js }}
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n rules material_form %}
{% block browser_title %}{% blocktrans %}Edit group role assignment{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Edit group role assignment{% endblocktrans %}{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{% form form=form %}{% endform %}
{% include "core/partials/save_button.html" %}
</form>
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n rules %}
{% load render_table from django_tables2 %}
{% block browser_title %}{% blocktrans %}Group roles{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Group roles{% endblocktrans %}{% endblock %}
{% block content %}
{% has_perm "alsijil.add_grouprole" user as add_group_role %}
{% if add_group_role %}
<a class="btn green waves-effect waves-light" href="{% url 'create_group_role' %}">
<i class="material-icons left">add</i>
{% trans "Create group role" %}
</a>
{% endif %}
{% render_table table %}
{% endblock %}
{% load i18n rules %}
{% has_perm "alsijil.assign_grouprole_for_group" user group as can_assign_group_role %}
<div class="collection">
{% for role in roles %}
<div class="collection-item">
<div class="row no-margin">
<div class="col s12 m5 l4 xl3 no-padding">
{% if can_assign_group_role %}
<a class="btn waves-effect waves-light right hide-on-med-and-up"
href="{% url "assign_group_role" group.pk role.pk %}?next={{ back_url }}">
<i class="material-icons center">add</i>
</a>
{% endif %}
<div class="btn-margin">
{% include "alsijil/group_role/chip.html" with role=role %}
</div>
</div>
<div class="col s12 m7 l8 xl9 no-padding">
{% if can_assign_group_role %}
<a class="btn waves-effect waves-light right hide-on-small-only"
href="{% url "assign_group_role" group.pk role.pk %}?next={{ back_url }}">
<i class="material-icons center">add</i>
</a>
{% endif %}
{% for assignment in role.assignments.all %}
{% include "alsijil/group_role/partials/assignment.html" with assignment=assignment group=group back_url=back_url %}
{% empty %}
<div class="grey-text darken-3">{% trans "No one assigned." %}</div>
{% endfor %}
</div>
</div>
</div>
{% endfor %}
</div>
<div class="alert primary">
<div>
<i class="material-icons left">info</i>
{% blocktrans %}
You can get some additional actions for each group role assignment if you click on the name of the
corresponding person.
{% endblocktrans %}
</div>
</div>
\ No newline at end of file
<a class="chip dropdown-trigger" href="#"
data-target="dropdown-{{ assignment.pk }}" title="{{ assignment }}">{{ assignment.person }}
{% if group not in assignment.groups.all %}
<small>({{ assignment.group_names }})</small>
{% endif %}
</a>
{% include "alsijil/group_role/partials/assignment_options.html" with assignment=assignment back_url=back_url %}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment