diff --git a/compensation/models.py b/compensation/models.py index 9d3e0ca5..ceca5733 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -5,6 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 17.11.20 """ +from django.contrib.auth.models import User from django.contrib.gis.db import models from django.core.validators import MinValueValidator 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) documents = models.ManyToManyField("konova.Document", blank=True) + # Users having access on this object + users = models.ManyToManyField(User) + @staticmethod def _generate_new_identifier() -> str: """ Generates a new identifier for the intervention object diff --git a/intervention/models.py b/intervention/models.py index 58cebcfb..f8243079 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -33,22 +33,29 @@ class Intervention(BaseObject): geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL) 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" registration_date = models.DateField(null=True, blank=True) # Refers to "Bestandskraft am" - binding_date = models.DateField(null=True, blank=True) + binding_on = models.DateField(null=True, blank=True) # Refers to "verzeichnen" - recorded_on = models.DateTimeField(default=None) - recorded_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL) + recorded_on = models.DateTimeField(default=None, null=True, blank=True) + 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 - 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 - payments = models.ManyToManyField(Payment, related_name="+") - compensations = models.ManyToManyField(Compensation, related_name="+") + payments = models.ManyToManyField(Payment, related_name="+", blank=True) + compensations = models.ManyToManyField(Compensation, related_name="+", blank=True) + + # Users having access on this object + users = models.ManyToManyField(User) def delete(self, *args, **kwargs): """ Custom delete functionality diff --git a/intervention/tables.py b/intervention/tables.py index 9d19ea7c..dea5ec7f 100644 --- a/intervention/tables.py +++ b/intervention/tables.py @@ -7,9 +7,11 @@ Created on: 01.12.20 """ from django.urls import reverse from django.utils.html import format_html +from django.utils.timezone import localtime from django.utils.translation import gettext_lazy as _ from intervention.models import Intervention +from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT from konova.utils.tables import BaseTable import django_tables2 as tables @@ -28,11 +30,13 @@ class InterventionTable(BaseTable): c = tables.Column( verbose_name=_("Checked"), orderable=True, - accessor="recorded_on", + empty_values=[], + accessor="checked_on", ) r = tables.Column( verbose_name=_("Registered"), orderable=True, + empty_values=[], accessor="recorded_on", ) lm = tables.Column( @@ -52,7 +56,7 @@ class InterventionTable(BaseTable): """ class Meta(BaseTable.Meta): - pass + template_name = "django_tables2/bootstrap4.html" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -78,6 +82,52 @@ class InterventionTable(BaseTable): ) 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): """ Renders possible actions for this record, such as delete. diff --git a/intervention/views.py b/intervention/views.py index ba7b1c66..722a7e05 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -26,7 +26,9 @@ def index_view(request: HttpRequest): template = "generic_index.html" user = request.user interventions = Intervention.objects.filter( - + deleted_on=None, # not deleted + next_version=None, # only newest versions + users__in=[user], # requesting user has access ) table = InterventionTable( request=request, diff --git a/konova/models.py b/konova/models.py index 5bf5b2a8..eb96dc76 100644 --- a/konova/models.py +++ b/konova/models.py @@ -35,9 +35,9 @@ class BaseObject(BaseResource): """ identifier = 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_by = models.ForeignKey(User, null=True, on_delete=models.SET_NULL, related_name="+") - comment = models.TextField() + deleted_on = models.DateTimeField(null=True, blank=True) + deleted_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name="+") + comment = models.TextField(null=True, blank=True) class Meta: abstract = True diff --git a/konova/static/css/konova.css b/konova/static/css/konova.css index 5f311331..dceb780e 100644 --- a/konova/static/css/konova.css +++ b/konova/static/css/konova.css @@ -72,7 +72,7 @@ a { text-decoration: none; } -nav{ +.navbar{ background-color: var(--rlp-red); } @@ -144,9 +144,35 @@ nav{ cursor: pointer; } +.dropdown-item.selected{ + background-color: var(--rlp-gray-light); +} + input:focus, textarea:focus, select: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; +} + +.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); } \ No newline at end of file diff --git a/konova/sub_settings/django_settings.py b/konova/sub_settings/django_settings.py index 20b28fa8..e06c1382 100644 --- a/konova/sub_settings/django_settings.py +++ b/konova/sub_settings/django_settings.py @@ -144,7 +144,7 @@ AUTH_PASSWORD_VALIDATORS = [ 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' diff --git a/konova/utils/tables.py b/konova/utils/tables.py index 65f9f4e3..196515ac 100644 --- a/konova/utils/tables.py +++ b/konova/utils/tables.py @@ -104,6 +104,28 @@ class BaseTable(tables.tables.Table): 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( + "", + 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( + "", + tooltip, + icon + ) + class ChoicesColumnForm(BaseForm): select = forms.ChoiceField( diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 9e5396eb..11732223 100644 Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index f1595f1e..ba953669 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -3,13 +3,13 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # -#: konova/forms.py:67 user/forms.py:38 +#: konova/forms.py:69 user/forms.py:38 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\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" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,49 +19,49 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: compensation/tables.py:18 compensation/tables.py:68 intervention/forms.py:26 -#: intervention/tables.py:19 +#: compensation/tables.py:18 compensation/tables.py:71 intervention/forms.py:26 +#: intervention/tables.py:22 msgid "Identifier" msgstr "Kennung" -#: compensation/tables.py:23 compensation/tables.py:73 intervention/forms.py:33 -#: intervention/tables.py:24 +#: compensation/tables.py:23 compensation/tables.py:76 intervention/forms.py:33 +#: intervention/tables.py:27 msgid "Title" msgstr "Titel" -#: compensation/tables.py:28 compensation/tables.py:78 +#: compensation/tables.py:28 compensation/tables.py:81 msgid "Created on" msgstr "Erstellt" -#: compensation/tables.py:33 compensation/tables.py:83 +#: compensation/tables.py:33 compensation/tables.py:86 msgid "Actions" msgstr "Aktionen" -#: compensation/tables.py:41 +#: compensation/tables.py:44 msgid "Compensations" 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 msgid "Compensation" msgstr "Kompensation" -#: compensation/tables.py:51 compensation/tables.py:101 -#: intervention/tables.py:74 intervention/tables.py:88 +#: compensation/tables.py:54 compensation/tables.py:107 +#: intervention/tables.py:79 intervention/tables.py:139 msgid "Open {}" msgstr "Öffne {}" -#: compensation/tables.py:56 compensation/tables.py:106 -#: intervention/tables.py:92 +#: compensation/tables.py:59 compensation/tables.py:112 +#: intervention/tables.py:143 msgid "Edit {}" msgstr "Bearbeite {}" -#: compensation/tables.py:60 compensation/tables.py:110 -#: intervention/tables.py:96 +#: compensation/tables.py:63 compensation/tables.py:116 +#: intervention/tables.py:147 msgid "Delete {}" msgstr "Lösche {}" -#: compensation/tables.py:91 +#: compensation/tables.py:97 msgid "Eco Accounts" msgstr "Ökokonten" @@ -133,41 +133,57 @@ msgstr "Neuer Eingriff" msgid "Edit intervention" msgstr "Eingriff bearbeiten" -#: intervention/tables.py:29 +#: intervention/tables.py:32 msgid "Checked" msgstr "Geprüft" -#: intervention/tables.py:34 +#: intervention/tables.py:38 msgid "Registered" msgstr "Verzeichnet" -#: intervention/tables.py:39 +#: intervention/tables.py:44 msgid "Last edit" msgstr "Zuletzt bearbeitet" -#: intervention/tables.py:59 +#: intervention/tables.py:64 msgid "Interventions" msgstr "Eingriffe" -#: intervention/tables.py:74 intervention/tables.py:85 +#: intervention/tables.py:79 intervention/tables.py:136 #: intervention/templates/intervention/open.html:8 #: konova/templates/konova/home.html:11 templates/navbar.html:22 msgid "Intervention" 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 msgid "Edit" msgstr "Bearbeiten" -#: intervention/views.py:58 +#: intervention/views.py:60 msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views.py:61 intervention/views.py:114 +#: intervention/views.py:63 intervention/views.py:116 msgid "Invalid input" msgstr "Eingabe fehlerhaft" -#: intervention/views.py:111 +#: intervention/views.py:113 msgid "{} edited" msgstr "{} bearbeitet" @@ -183,19 +199,19 @@ msgstr "Hierfür müssen Sie Administrator sein!" msgid "You need to be part of another user group." msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" -#: konova/forms.py:40 +#: konova/forms.py:42 msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:66 +#: konova/forms.py:68 msgid "Confirm" msgstr "Bestätigen" -#: konova/forms.py:78 +#: konova/forms.py:80 msgid "Remove" msgstr "Entferne" -#: konova/forms.py:80 +#: konova/forms.py:82 msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen"