Intervention tables and model adjustments

* adds user access relation to certain models
* adds pagination to tables
* adds checked_on/_by attributes to intervention model
* adds custom column rendering for checked and registered columns
* adds first simple index filtering of default interventions for user
* adds translations
This commit is contained in:
mipel 2021-07-21 15:40:34 +02:00
parent 8f0db2ae3e
commit 67f415c2e3
10 changed files with 170 additions and 43 deletions

View File

@ -5,6 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 17.11.20 Created on: 17.11.20
""" """
from django.contrib.auth.models import User
from django.contrib.gis.db import models from django.contrib.gis.db import models
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.utils import timezone from django.utils import timezone
@ -74,6 +75,9 @@ class Compensation(BaseObject):
geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL) geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL)
documents = models.ManyToManyField("konova.Document", blank=True) documents = models.ManyToManyField("konova.Document", blank=True)
# Users having access on this object
users = models.ManyToManyField(User)
@staticmethod @staticmethod
def _generate_new_identifier() -> str: def _generate_new_identifier() -> str:
""" Generates a new identifier for the intervention object """ Generates a new identifier for the intervention object

View File

@ -33,22 +33,29 @@ class Intervention(BaseObject):
geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL) geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL)
documents = models.ManyToManyField("konova.Document", blank=True) documents = models.ManyToManyField("konova.Document", blank=True)
# Checks
checked_on = models.DateTimeField(default=None, null=True, blank=True)
checked_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
# Refers to "zugelassen am" # Refers to "zugelassen am"
registration_date = models.DateField(null=True, blank=True) registration_date = models.DateField(null=True, blank=True)
# Refers to "Bestandskraft am" # Refers to "Bestandskraft am"
binding_date = models.DateField(null=True, blank=True) binding_on = models.DateField(null=True, blank=True)
# Refers to "verzeichnen" # Refers to "verzeichnen"
recorded_on = models.DateTimeField(default=None) recorded_on = models.DateTimeField(default=None, null=True, blank=True)
recorded_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL) recorded_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
# Holds which intervention is simply a newer version of this dataset # Holds which intervention is simply a newer version of this dataset
next_version = models.ForeignKey("Intervention", null=True, on_delete=models.DO_NOTHING) next_version = models.ForeignKey("Intervention", null=True, blank=True, on_delete=models.DO_NOTHING)
# Compensation or payments, one-directional # Compensation or payments, one-directional
payments = models.ManyToManyField(Payment, related_name="+") payments = models.ManyToManyField(Payment, related_name="+", blank=True)
compensations = models.ManyToManyField(Compensation, related_name="+") compensations = models.ManyToManyField(Compensation, related_name="+", blank=True)
# Users having access on this object
users = models.ManyToManyField(User)
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
""" Custom delete functionality """ Custom delete functionality

View File

@ -7,9 +7,11 @@ Created on: 01.12.20
""" """
from django.urls import reverse from django.urls import reverse
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.timezone import localtime
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from intervention.models import Intervention from intervention.models import Intervention
from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT
from konova.utils.tables import BaseTable from konova.utils.tables import BaseTable
import django_tables2 as tables import django_tables2 as tables
@ -28,11 +30,13 @@ class InterventionTable(BaseTable):
c = tables.Column( c = tables.Column(
verbose_name=_("Checked"), verbose_name=_("Checked"),
orderable=True, orderable=True,
accessor="recorded_on", empty_values=[],
accessor="checked_on",
) )
r = tables.Column( r = tables.Column(
verbose_name=_("Registered"), verbose_name=_("Registered"),
orderable=True, orderable=True,
empty_values=[],
accessor="recorded_on", accessor="recorded_on",
) )
lm = tables.Column( lm = tables.Column(
@ -52,7 +56,7 @@ class InterventionTable(BaseTable):
""" """
class Meta(BaseTable.Meta): class Meta(BaseTable.Meta):
pass template_name = "django_tables2/bootstrap4.html"
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -78,6 +82,52 @@ class InterventionTable(BaseTable):
) )
return format_html(html) return format_html(html)
def render_c(self, value, record: Intervention):
""" Renders the checked column for an intervention
Args:
value (str): The identifier value
record (Intervention): The intervention record
Returns:
"""
html = ""
checked = value is not None
tooltip = _("Not checked yet")
if checked:
value = localtime(value)
checked_on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
tooltip = _("Checked on {} by {}").format(checked_on, record.checked_by)
html += self.render_checked_star(
tooltip=tooltip,
icn_filled=checked,
)
return format_html(html)
def render_r(self, value, record: Intervention):
""" Renders the registered column for an intervention
Args:
value (str): The identifier value
record (Intervention): The intervention record
Returns:
"""
html = ""
checked = value is not None
tooltip = _("Not registered yet")
if checked:
value = localtime(value)
checked_on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
tooltip = _("Registered on {} by {}").format(checked_on, record.checked_by)
html += self.render_bookmark(
tooltip=tooltip,
icn_filled=checked,
)
return format_html(html)
def render_ac(self, value, record): def render_ac(self, value, record):
""" """
Renders possible actions for this record, such as delete. Renders possible actions for this record, such as delete.

View File

@ -26,7 +26,9 @@ def index_view(request: HttpRequest):
template = "generic_index.html" template = "generic_index.html"
user = request.user user = request.user
interventions = Intervention.objects.filter( interventions = Intervention.objects.filter(
deleted_on=None, # not deleted
next_version=None, # only newest versions
users__in=[user], # requesting user has access
) )
table = InterventionTable( table = InterventionTable(
request=request, request=request,

View File

@ -35,9 +35,9 @@ class BaseObject(BaseResource):
""" """
identifier = models.CharField(max_length=1000, null=True, blank=True) identifier = models.CharField(max_length=1000, null=True, blank=True)
title = models.CharField(max_length=1000, null=True, blank=True) title = models.CharField(max_length=1000, null=True, blank=True)
deleted_on = models.DateTimeField(null=True) deleted_on = models.DateTimeField(null=True, blank=True)
deleted_by = models.ForeignKey(User, null=True, on_delete=models.SET_NULL, related_name="+") deleted_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name="+")
comment = models.TextField() comment = models.TextField(null=True, blank=True)
class Meta: class Meta:
abstract = True abstract = True

View File

@ -72,7 +72,7 @@ a {
text-decoration: none; text-decoration: none;
} }
nav{ .navbar{
background-color: var(--rlp-red); background-color: var(--rlp-red);
} }
@ -144,9 +144,35 @@ nav{
cursor: pointer; cursor: pointer;
} }
.dropdown-item.selected{
background-color: var(--rlp-gray-light);
}
input:focus, textarea:focus, select:focus{ input:focus, textarea:focus, select:focus{
border: 1px solid var(--rlp-red) !important; border: 1px solid var(--rlp-red) !important;
box-shadow: 0 0 3px var(--rlp-red) !important; box-shadow: 0 0 3px var(--rlp-red) !important;
-moz-box-shadow: 0 0 3px var(--rlp-red) !important; -moz-box-shadow: 0 0 3px var(--rlp-red) !important;
-webkit-box-shadow: 0 0 3px var(--rlp-red) !important; -webkit-box-shadow: 0 0 3px var(--rlp-red) !important;
}
.check-star{
color: goldenrod;
}
.registered-bookmark{
color: green;
}
/* PAGINATION */
.page-item > .page-link{
color: var(--rlp-red);
}
.page-link:focus{
border: 1px solid var(--rlp-red) !important;
box-shadow: 0 0 3px var(--rlp-red) !important;
-moz-box-shadow: 0 0 3px var(--rlp-red) !important;
-webkit-box-shadow: 0 0 3px var(--rlp-red) !important;
}
.page-item.active > .page-link{
background-color: var(--rlp-red);
border-color: var(--rlp-red);
} }

View File

@ -144,7 +144,7 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'en-us'
DEFAULT_DATE_TIME_FORMAT = 'YYYY-MM-DD hh:mm:ss' DEFAULT_DATE_TIME_FORMAT = '%d.%m.%Y %H:%M:%S'
TIME_ZONE = 'Europe/Berlin' TIME_ZONE = 'Europe/Berlin'

View File

@ -104,6 +104,28 @@ class BaseTable(tables.tables.Table):
icon icon
) )
def render_checked_star(self, tooltip: str = None, icn_filled: bool = False):
"""
Returns a star icon
"""
icon = "fas fa-star check-star" if icn_filled else "far fa-star"
return format_html(
"<em title='{}' class='{}'></em>",
tooltip,
icon
)
def render_bookmark(self, tooltip: str = None, icn_filled: bool = False):
"""
Returns a bookmark icon
"""
icon = "fas fa-bookmark registered-bookmark" if icn_filled else "far fa-bookmark"
return format_html(
"<em title='{}' class='{}'></em>",
tooltip,
icon
)
class ChoicesColumnForm(BaseForm): class ChoicesColumnForm(BaseForm):
select = forms.ChoiceField( select = forms.ChoiceField(

Binary file not shown.

View File

@ -3,13 +3,13 @@
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# #
#: konova/forms.py:67 user/forms.py:38 #: konova/forms.py:69 user/forms.py:38
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-07-21 13:28+0200\n" "POT-Creation-Date: 2021-07-21 15:07+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -19,49 +19,49 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: compensation/tables.py:18 compensation/tables.py:68 intervention/forms.py:26 #: compensation/tables.py:18 compensation/tables.py:71 intervention/forms.py:26
#: intervention/tables.py:19 #: intervention/tables.py:22
msgid "Identifier" msgid "Identifier"
msgstr "Kennung" msgstr "Kennung"
#: compensation/tables.py:23 compensation/tables.py:73 intervention/forms.py:33 #: compensation/tables.py:23 compensation/tables.py:76 intervention/forms.py:33
#: intervention/tables.py:24 #: intervention/tables.py:27
msgid "Title" msgid "Title"
msgstr "Titel" msgstr "Titel"
#: compensation/tables.py:28 compensation/tables.py:78 #: compensation/tables.py:28 compensation/tables.py:81
msgid "Created on" msgid "Created on"
msgstr "Erstellt" msgstr "Erstellt"
#: compensation/tables.py:33 compensation/tables.py:83 #: compensation/tables.py:33 compensation/tables.py:86
msgid "Actions" msgid "Actions"
msgstr "Aktionen" msgstr "Aktionen"
#: compensation/tables.py:41 #: compensation/tables.py:44
msgid "Compensations" msgid "Compensations"
msgstr "Kompensationen" msgstr "Kompensationen"
#: compensation/tables.py:48 compensation/tables.py:98 #: compensation/tables.py:51 compensation/tables.py:104
#: konova/templates/konova/home.html:49 templates/navbar.html:28 #: konova/templates/konova/home.html:49 templates/navbar.html:28
msgid "Compensation" msgid "Compensation"
msgstr "Kompensation" msgstr "Kompensation"
#: compensation/tables.py:51 compensation/tables.py:101 #: compensation/tables.py:54 compensation/tables.py:107
#: intervention/tables.py:74 intervention/tables.py:88 #: intervention/tables.py:79 intervention/tables.py:139
msgid "Open {}" msgid "Open {}"
msgstr "Öffne {}" msgstr "Öffne {}"
#: compensation/tables.py:56 compensation/tables.py:106 #: compensation/tables.py:59 compensation/tables.py:112
#: intervention/tables.py:92 #: intervention/tables.py:143
msgid "Edit {}" msgid "Edit {}"
msgstr "Bearbeite {}" msgstr "Bearbeite {}"
#: compensation/tables.py:60 compensation/tables.py:110 #: compensation/tables.py:63 compensation/tables.py:116
#: intervention/tables.py:96 #: intervention/tables.py:147
msgid "Delete {}" msgid "Delete {}"
msgstr "Lösche {}" msgstr "Lösche {}"
#: compensation/tables.py:91 #: compensation/tables.py:97
msgid "Eco Accounts" msgid "Eco Accounts"
msgstr "Ökokonten" msgstr "Ökokonten"
@ -133,41 +133,57 @@ msgstr "Neuer Eingriff"
msgid "Edit intervention" msgid "Edit intervention"
msgstr "Eingriff bearbeiten" msgstr "Eingriff bearbeiten"
#: intervention/tables.py:29 #: intervention/tables.py:32
msgid "Checked" msgid "Checked"
msgstr "Geprüft" msgstr "Geprüft"
#: intervention/tables.py:34 #: intervention/tables.py:38
msgid "Registered" msgid "Registered"
msgstr "Verzeichnet" msgstr "Verzeichnet"
#: intervention/tables.py:39 #: intervention/tables.py:44
msgid "Last edit" msgid "Last edit"
msgstr "Zuletzt bearbeitet" msgstr "Zuletzt bearbeitet"
#: intervention/tables.py:59 #: intervention/tables.py:64
msgid "Interventions" msgid "Interventions"
msgstr "Eingriffe" msgstr "Eingriffe"
#: intervention/tables.py:74 intervention/tables.py:85 #: intervention/tables.py:79 intervention/tables.py:136
#: intervention/templates/intervention/open.html:8 #: intervention/templates/intervention/open.html:8
#: konova/templates/konova/home.html:11 templates/navbar.html:22 #: konova/templates/konova/home.html:11 templates/navbar.html:22
msgid "Intervention" msgid "Intervention"
msgstr "Eingriff" msgstr "Eingriff"
#: intervention/tables.py:98
msgid "Not checked yet"
msgstr "Noch nicht geprüft"
#: intervention/tables.py:102
msgid "Checked on {} by {}"
msgstr "Am {} von {} geprüft worden"
#: intervention/tables.py:121
msgid "Not registered yet"
msgstr "Noch nicht verzeichnet"
#: intervention/tables.py:125
msgid "Registered on {} by {}"
msgstr "Am {} von {} verzeichnet worden"
#: intervention/templates/intervention/open.html:12 #: intervention/templates/intervention/open.html:12
msgid "Edit" msgid "Edit"
msgstr "Bearbeiten" msgstr "Bearbeiten"
#: intervention/views.py:58 #: intervention/views.py:60
msgid "Intervention {} added" msgid "Intervention {} added"
msgstr "Eingriff {} hinzugefügt" msgstr "Eingriff {} hinzugefügt"
#: intervention/views.py:61 intervention/views.py:114 #: intervention/views.py:63 intervention/views.py:116
msgid "Invalid input" msgid "Invalid input"
msgstr "Eingabe fehlerhaft" msgstr "Eingabe fehlerhaft"
#: intervention/views.py:111 #: intervention/views.py:113
msgid "{} edited" msgid "{} edited"
msgstr "{} bearbeitet" msgstr "{} bearbeitet"
@ -183,19 +199,19 @@ msgstr "Hierfür müssen Sie Administrator sein!"
msgid "You need to be part of another user group." msgid "You need to be part of another user group."
msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!"
#: konova/forms.py:40 #: konova/forms.py:42
msgid "Not editable" msgid "Not editable"
msgstr "Nicht editierbar" msgstr "Nicht editierbar"
#: konova/forms.py:66 #: konova/forms.py:68
msgid "Confirm" msgid "Confirm"
msgstr "Bestätigen" msgstr "Bestätigen"
#: konova/forms.py:78 #: konova/forms.py:80
msgid "Remove" msgid "Remove"
msgstr "Entferne" msgstr "Entferne"
#: konova/forms.py:80 #: konova/forms.py:82
msgid "You are about to remove {} {}" msgid "You are about to remove {} {}"
msgstr "Sie sind dabei {} {} zu löschen" msgstr "Sie sind dabei {} {} zu löschen"