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

Merge branch '45-statistics-on-personal-notes-by-free-text-filters' into 'master'

Resolve "Statistics on personal notes by free-text filters"

Closes #45

See merge request BiscuIT/BiscuIT-App-Alsijil!27
parents cbf8be4e f427c81f
No related branches found
No related tags found
1 merge request!27Resolve "Statistics on personal notes by free-text filters"
...@@ -7,7 +7,7 @@ from datetime import datetime ...@@ -7,7 +7,7 @@ from datetime import datetime
from biscuit.apps.chronos.models import Room from biscuit.apps.chronos.models import Room
from biscuit.core.models import Group, Person from biscuit.core.models import Group, Person
from .models import LessonDocumentation, PersonalNote from .models import LessonDocumentation, PersonalNote, PersonalNoteFilter
class LessonDocumentationForm(forms.ModelForm): class LessonDocumentationForm(forms.ModelForm):
...@@ -58,3 +58,9 @@ class RegisterAbsenceForm(forms.Form): ...@@ -58,3 +58,9 @@ class RegisterAbsenceForm(forms.Form):
absent = forms.BooleanField(label=_('Absent'), initial=True, required=False) absent = forms.BooleanField(label=_('Absent'), initial=True, required=False)
excused = forms.BooleanField(label=_('Excused'), initial=True, required=False) excused = forms.BooleanField(label=_('Excused'), initial=True, required=False)
remarks = forms.CharField(label=_('Remarks'), max_length=30, required=False) remarks = forms.CharField(label=_('Remarks'), max_length=30, required=False)
class PersonalNoteFilterForm(forms.ModelForm):
class Meta:
model = PersonalNoteFilter
fields = ['identifier', 'description', 'regex']
...@@ -22,6 +22,11 @@ MENUS = { ...@@ -22,6 +22,11 @@ MENUS = {
'name': _('Register absence'), 'name': _('Register absence'),
'url': 'register_absence', 'url': 'register_absence',
'validators': ['menu_generator.validators.is_superuser'] 'validators': ['menu_generator.validators.is_superuser']
},
{
'name': _('Personal note filters'),
'url': 'list_personal_note_filters',
'validators': ['menu_generator.validators.is_superuser']
} }
] ]
} }
......
from django.utils.translation import ugettext_lazy as _
import django_tables2 as tables
from django_tables2.utils import A
class PersonalNoteFilterTable(tables.Table):
class Meta:
attrs = {'class': 'table table-striped table-bordered table-hover table-responsive-xl'}
identifier = tables.Column()
description = tables.Column()
regex = tables.Column()
edit_filter = tables.LinkColumn(
'edit_personal_note_filter', args=[A('id')], text=_('Edit'))
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load bootstrap4 i18n static font_awesome %}
{% block bootstrap4_extra_head %}
{{ block.super }}
{{ personal_note_filter_form.media.css }}
{% endblock %}
{% block bootstrap4_extra_script %}
{{ block.super }}
{{ personal_note_filter_form.media.js }}
{% endblock %}
{% block bootstrap4_title %}{% blocktrans%}Manage personal note filter{% endblocktrans %} - {{ block.super }}{% endblock %}
{% block page_title %}{% blocktrans %}Manage personal note filter{% endblocktrans %}{% endblock %}
{% block content %}
<div class="d-flex justify-content-between">
<div class="btn-group" role="group" aria-label="Filter actions">
{% if personal_note_filter %}
<a href="{% url 'delete_personal_note_filter' personal_note_filter.id %}" class="btn btn-danger">
{% fa 'trash-o' %}
</a>
{% endif %}
</div>
</div>
<form method="post">
{% csrf_token %}
{% bootstrap_form personal_note_filter_form %}
<button type="submit" class="btn btn-dark">
{% blocktrans %}Save{% endblocktrans %}
</button>
</form>
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load bootstrap4 i18n static font_awesome %}
{% block bootstrap4_extra_head %}
{{ block.super }}
{{ personal_note_filters_form.media.css }}
{% endblock %}
{% block bootstrap4_extra_script %}
{{ block.super }}
{{ personal_note_filters_form.media.js }}
{% endblock %}
{% block bootstrap4_title %}{% blocktrans%}Manage personal note filters{% endblocktrans %} - {{ block.super }}{% endblock %}
{% block page_title %}{% blocktrans %}Manage personal note filters{% endblocktrans %}{% endblock %}
{% block content %}
<div class="d-flex justify-content-between">
<div class="btn-group" role="group" aria-label="Filter actions">
{% if personal_note_filters %}
<a href="{% url 'delete_personal_note_filters' personal_note_filters.id %}" class="btn btn-danger">
{% fa 'trash-o' %}
</a>
{% endif %}
</div>
</div>
<form method="post">
{% csrf_token %}
{% bootstrap_form personal_note_filters_form %}
<button type="submit" class="btn btn-dark">
{% blocktrans %}Save{% endblocktrans %}
</button>
</form>
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load bootstrap4 i18n font_awesome %}
{% load render_table from django_tables2 %}
{% block bootstrap4_title %}{% blocktrans %}List of all personal note filters{% endblocktrans %} - {{ block.super }}{% endblock %}
{% block page_title %}{% blocktrans %}List of all personal note filters{% endblocktrans %}{% endblock %}
{% block content %}
<div class="btn-group" role="group" aria-lable="Filter actions">
<a href="{% url 'create_personal_note_filter' %}" class="btn btn-dark">
{% fa 'plus' %}
</a>
</div>
{% render_table personal_note_filters_table %}
{% endblock %}
...@@ -14,4 +14,12 @@ urlpatterns = [ ...@@ -14,4 +14,12 @@ urlpatterns = [
name='full_register_group'), name='full_register_group'),
path('absence/new', views.register_absence, path('absence/new', views.register_absence,
name='register_absence'), name='register_absence'),
path('filters/list', views.list_personal_note_filters,
name='list_personal_note_filters'),
path('filters/create', views.edit_personal_note_filter,
name='create_personal_note_filter'),
path('filters/edit/<int:id>', views.edit_personal_note_filter,
name='edit_personal_note_filter'),
path('filters/delete/<int:id_>', views.delete_personal_note_filter,
name='delete_personal_note_filter')
] ]
...@@ -9,14 +9,17 @@ from django.shortcuts import get_object_or_404, redirect, render ...@@ -9,14 +9,17 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django_tables2 import RequestConfig
from biscuit.apps.chronos.models import LessonPeriod from biscuit.apps.chronos.models import LessonPeriod
from biscuit.apps.chronos.util import CalendarWeek from biscuit.apps.chronos.util import CalendarWeek
from biscuit.core.models import Group, Person from biscuit.core.models import Group, Person
from biscuit.core.decorators import admin_required from biscuit.core.decorators import admin_required
from biscuit.core.util import messages from biscuit.core.util import messages
from .forms import LessonDocumentationForm, PersonalNoteFormSet, RegisterAbsenceForm, SelectForm from .forms import LessonDocumentationForm, PersonalNoteFormSet, RegisterAbsenceForm, SelectForm, PersonalNoteFilterForm
from .models import LessonDocumentation, PersonalNoteFilter from .models import LessonDocumentation, PersonalNoteFilter
from .tables import PersonalNoteFilterTable
@login_required @login_required
...@@ -247,3 +250,54 @@ def register_absence(request: HttpRequest) -> HttpResponse: ...@@ -247,3 +250,54 @@ def register_absence(request: HttpRequest) -> HttpResponse:
context['register_absence_form'] = register_absence_form context['register_absence_form'] = register_absence_form
return render(request, 'alsijil/register_absence.html', context) return render(request, 'alsijil/register_absence.html', context)
def list_personal_note_filters(request: HttpRequest) -> HttpResponse:
context = {}
personal_note_filters = PersonalNoteFilter.objects.all()
# Prepare table
personal_note_filters_table = PersonalNoteFilterTable(personal_note_filters)
RequestConfig(request).configure(personal_note_filters_table)
context['personal_note_filters_table'] = personal_note_filters_table
return render(request, 'alsijil/personal_note_filters.html', context)
def edit_personal_note_filter(request: HttpRequest, id: Optional['int'] = None) -> HttpResponse:
context = {}
if id:
personal_note_filter = PersonalNoteFilter.objects.get(id=id)
context['personal_note_filter'] = personal_note_filter
personal_note_filter_form = PersonalNoteFilterForm(
request.POST or None, instance=personal_note_filter)
else:
personal_note_filter_form = PersonalNoteFilterForm(
request.POST or None)
if request.method == 'POST':
if personal_note_filter_form.is_valid():
personal_note_filter_form.save(commit=True)
messages.success(request, _('The filter has been saved'))
return redirect('list_personal_note_filters')
context['personal_note_filter_form'] = personal_note_filter_form
return render(request, 'alsijil/manage_personal_note_filter.html', context)
@admin_required
def delete_personal_note_filter(request: HttpRequest, id_: int) -> HttpResponse:
context = {}
personal_note_filter = get_object_or_404(PersonalNoteFilter, pk=id_)
PersonalNoteFilter.objects.filter(pk=id_).delete()
messages.success(request, _('The filter has been deleted.'))
context['personal_note_filter'] = personal_note_filter
return redirect('list_personal_note_filters')
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