Merge pull request 'master' (#224) from master into Docker

Reviewed-on: SGD-Nord/konova#224
pull/380/head
mpeltriaux 2 years ago
commit bc331cfaf8

@ -14,11 +14,11 @@ from django.utils.translation import gettext_lazy as _
from compensation.filters.compensation import CompensationTableFilter from compensation.filters.compensation import CompensationTableFilter
from compensation.models import Compensation from compensation.models import Compensation
from konova.utils.message_templates import DATA_IS_UNCHECKED, DATA_CHECKED_ON_TEMPLATE, DATA_CHECKED_PREVIOUSLY_TEMPLATE from konova.utils.message_templates import DATA_IS_UNCHECKED, DATA_CHECKED_ON_TEMPLATE, DATA_CHECKED_PREVIOUSLY_TEMPLATE
from konova.utils.tables import BaseTable, TableRenderMixin from konova.utils.tables import BaseTable, TableRenderMixin, TableOrderMixin
import django_tables2 as tables import django_tables2 as tables
class CompensationTable(BaseTable, TableRenderMixin): class CompensationTable(BaseTable, TableRenderMixin, TableOrderMixin):
id = tables.Column( id = tables.Column(
verbose_name=_("Identifier"), verbose_name=_("Identifier"),
orderable=True, orderable=True,
@ -31,7 +31,7 @@ class CompensationTable(BaseTable, TableRenderMixin):
) )
d = tables.Column( d = tables.Column(
verbose_name=_("Parcel gmrkng"), verbose_name=_("Parcel gmrkng"),
orderable=True, orderable=False,
accessor="geometry", accessor="geometry",
) )
c = tables.Column( c = tables.Column(
@ -126,28 +126,6 @@ class CompensationTable(BaseTable, TableRenderMixin):
) )
return format_html(html) return format_html(html)
def render_d(self, value, record: Compensation):
""" Renders the parcel district column for a compensation
Args:
value (str): The geometry
record (Compensation): The compensation record
Returns:
"""
parcels = value.get_underlying_parcels().values_list(
"parcel_group__name",
flat=True
).distinct()
html = render_to_string(
"table/gmrkng_col.html",
{
"entries": parcels
}
)
return html
def render_r(self, value, record: Compensation): def render_r(self, value, record: Compensation):
""" Renders the registered column for a compensation """ Renders the registered column for a compensation
@ -170,20 +148,3 @@ class CompensationTable(BaseTable, TableRenderMixin):
) )
return format_html(html) return format_html(html)
def render_e(self, value, record: Compensation):
""" Renders the editable column for a compensation
Args:
value (str): The identifier value
record (Compensation): The compensation record
Returns:
"""
has_access = record.is_shared_with(self.user)
html = self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
)
return format_html(html)

@ -13,12 +13,12 @@ from django.utils.translation import gettext_lazy as _
from compensation.filters.eco_account import EcoAccountTableFilter from compensation.filters.eco_account import EcoAccountTableFilter
from compensation.models import EcoAccount from compensation.models import EcoAccount
from konova.utils.tables import TableRenderMixin, BaseTable from konova.utils.tables import TableRenderMixin, BaseTable, TableOrderMixin
import django_tables2 as tables import django_tables2 as tables
class EcoAccountTable(BaseTable, TableRenderMixin): class EcoAccountTable(BaseTable, TableRenderMixin, TableOrderMixin):
id = tables.Column( id = tables.Column(
verbose_name=_("Identifier"), verbose_name=_("Identifier"),
orderable=True, orderable=True,
@ -31,7 +31,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
) )
d = tables.Column( d = tables.Column(
verbose_name=_("Parcel gmrkng"), verbose_name=_("Parcel gmrkng"),
orderable=True, orderable=False,
accessor="geometry", accessor="geometry",
) )
av = tables.Column( av = tables.Column(
@ -113,28 +113,6 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
html = render_to_string("konova/widgets/progressbar.html", {"value": value_relative}) html = render_to_string("konova/widgets/progressbar.html", {"value": value_relative})
return format_html(html) return format_html(html)
def render_d(self, value, record):
""" Renders the parcel district column for a compensation
Args:
value (str): The geometry
record (Compensation): The compensation record
Returns:
"""
parcels = value.get_underlying_parcels().values_list(
"parcel_group__name",
flat=True
).distinct()
html = render_to_string(
"table/gmrkng_col.html",
{
"entries": parcels
}
)
return html
def render_r(self, value, record: EcoAccount): def render_r(self, value, record: EcoAccount):
""" Renders the recorded column for an eco account """ Renders the recorded column for an eco account
@ -156,23 +134,3 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
icn_filled=checked, icn_filled=checked,
) )
return format_html(html) return format_html(html)
def render_e(self, value, record: EcoAccount):
""" Renders the editable column for an eco account
Args:
value (str): The identifier value
record (EcoAccount): The eco account record
Returns:
"""
html = ""
# Do not use value in here, since value does use unprefetched 'users' manager, where record has already
# prefetched users data
has_access = record.is_shared_with(self.user)
html += self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
)
return format_html(html)

@ -6,21 +6,18 @@ Created on: 19.08.21
""" """
from django.http import HttpRequest from django.http import HttpRequest
from django.template.loader import render_to_string
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 django.urls import reverse from django.urls import reverse
import django_tables2 as tables import django_tables2 as tables
from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT from konova.utils.tables import BaseTable, TableRenderMixin, TableOrderMixin
from konova.utils.tables import BaseTable, TableRenderMixin
from ema.filters import EmaTableFilter from ema.filters import EmaTableFilter
from ema.models import Ema from ema.models import Ema
class EmaTable(BaseTable, TableRenderMixin): class EmaTable(BaseTable, TableRenderMixin, TableOrderMixin):
""" """
Since EMA and compensation are basically the same, we can reuse CompensationTableFilter and extend the EMA filter Since EMA and compensation are basically the same, we can reuse CompensationTableFilter and extend the EMA filter
in the future by inheriting. in the future by inheriting.
@ -37,7 +34,7 @@ class EmaTable(BaseTable, TableRenderMixin):
) )
d = tables.Column( d = tables.Column(
verbose_name=_("Parcel gmrkng"), verbose_name=_("Parcel gmrkng"),
orderable=True, orderable=False,
accessor="geometry", accessor="geometry",
) )
r = tables.Column( r = tables.Column(
@ -93,28 +90,6 @@ class EmaTable(BaseTable, TableRenderMixin):
) )
return format_html(html) return format_html(html)
def render_d(self, value, record: Ema):
""" Renders the parcel district column for a ema
Args:
value (str): The geometry
record (Ema): The ema record
Returns:
"""
parcels = value.get_underlying_parcels().values_list(
"parcel_group__name",
flat=True
).distinct()
html = render_to_string(
"table/gmrkng_col.html",
{
"entries": parcels
}
)
return html
def render_r(self, value, record: Ema): def render_r(self, value, record: Ema):
""" Renders the registered column for a EMA """ Renders the registered column for a EMA
@ -136,22 +111,3 @@ class EmaTable(BaseTable, TableRenderMixin):
icn_filled=recorded, icn_filled=recorded,
) )
return format_html(html) return format_html(html)
def render_e(self, value, record: Ema):
""" Renders the editable column for a EMA
Args:
value (str): The identifier value
record (Ema): The EMA record
Returns:
"""
html = ""
has_access = record.is_shared_with(self.user)
html += self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
)
return format_html(html)

@ -39,9 +39,8 @@ def index_view(request: HttpRequest):
template = "generic_index.html" template = "generic_index.html"
emas = Ema.objects.filter( emas = Ema.objects.filter(
deleted=None, deleted=None,
).order_by(
"-modified"
) )
table = EmaTable( table = EmaTable(
request, request,
queryset=emas queryset=emas

@ -14,11 +14,11 @@ from django.utils.translation import gettext_lazy as _
from intervention.filters import InterventionTableFilter from intervention.filters import InterventionTableFilter
from intervention.models import Intervention from intervention.models import Intervention
from konova.utils.message_templates import DATA_CHECKED_ON_TEMPLATE, DATA_IS_UNCHECKED, DATA_CHECKED_PREVIOUSLY_TEMPLATE from konova.utils.message_templates import DATA_CHECKED_ON_TEMPLATE, DATA_IS_UNCHECKED, DATA_CHECKED_PREVIOUSLY_TEMPLATE
from konova.utils.tables import BaseTable, TableRenderMixin from konova.utils.tables import BaseTable, TableRenderMixin, TableOrderMixin
import django_tables2 as tables import django_tables2 as tables
class InterventionTable(BaseTable, TableRenderMixin): class InterventionTable(BaseTable, TableRenderMixin, TableOrderMixin):
id = tables.Column( id = tables.Column(
verbose_name=_("Identifier"), verbose_name=_("Identifier"),
orderable=True, orderable=True,
@ -31,7 +31,7 @@ class InterventionTable(BaseTable, TableRenderMixin):
) )
d = tables.Column( d = tables.Column(
verbose_name=_("Parcel gmrkng"), verbose_name=_("Parcel gmrkng"),
orderable=True, orderable=False,
accessor="geometry", accessor="geometry",
) )
c = tables.Column( c = tables.Column(
@ -124,28 +124,6 @@ class InterventionTable(BaseTable, TableRenderMixin):
) )
return format_html(html) return format_html(html)
def render_d(self, value, record: Intervention):
""" Renders the parcel district column for an intervention
Args:
value (str): The intervention geometry
record (Intervention): The intervention record
Returns:
"""
parcels = value.get_underlying_parcels().values_list(
"parcel_group__name",
flat=True
).distinct()
html = render_to_string(
"table/gmrkng_col.html",
{
"entries": parcels
}
)
return html
def render_r(self, value, record: Intervention): def render_r(self, value, record: Intervention):
""" Renders the recorded column for an intervention """ Renders the recorded column for an intervention
@ -168,22 +146,3 @@ class InterventionTable(BaseTable, TableRenderMixin):
) )
return format_html(html) return format_html(html)
def render_e(self, value, record: Intervention):
""" Renders the editable column for an intervention
Args:
value (str): The identifier value
record (Intervention): The intervention record
Returns:
"""
html = ""
has_access = record.is_shared_with(self.user)
html += self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
)
return format_html(html)

@ -213,12 +213,9 @@ class Geometry(BaseResource):
geojson (dict): The FeatureCollection json (as dict) geojson (dict): The FeatureCollection json (as dict)
""" """
geom = self.geom geom = self.geom
geom.transform(ct=srid) if geom.srid != srid:
geom.transform(ct=srid)
polygons = []
for coords in geom.coords:
p = Polygon(coords[0], srid=geom.srid)
polygons.append(p)
geojson = { geojson = {
"type": "FeatureCollection", "type": "FeatureCollection",
"crs": { "crs": {
@ -230,8 +227,8 @@ class Geometry(BaseResource):
"features": [ "features": [
{ {
"type": "Feature", "type": "Feature",
"geometry": json.loads(x.geojson) "geometry": json.loads(geom.json),
} for x in polygons }
] ]
} }
return geojson return geojson

@ -10,5 +10,5 @@ BASE_TITLE_SHORT = "KSP"
BASE_TITLE = "KSP - Kompensationsverzeichnis Service Portal" BASE_TITLE = "KSP - Kompensationsverzeichnis Service Portal"
BASE_FRONTEND_TITLE = "Kompensationsverzeichnis Service Portal" BASE_FRONTEND_TITLE = "Kompensationsverzeichnis Service Portal"
TAB_TITLE_IDENTIFIER = "tab_title" TAB_TITLE_IDENTIFIER = "tab_title"
HELP_LINK = "https://dienste.naturschutz.rlp.de/doku/doku.php?id=ksp:start" HELP_LINK = "https://dienste.naturschutz.rlp.de/doku/doku.php?id=ksp2:start"
IMPRESSUM_LINK = "https://naturschutz.rlp.de/index.php?q=impressum" IMPRESSUM_LINK = "https://naturschutz.rlp.de/index.php?q=impressum"

@ -1,7 +1,8 @@
{% load i18n l10n %} {% load i18n l10n fontawesome_5 %}
<div class="table-container w-100 scroll-300"> <div class="table-container w-100 scroll-300">
{% if parcels|length == 0 %} {% if parcels|length == 0 %}
<article class="alert alert-info"> <article class="alert alert-info">
{% fa5_icon 'search-location' %}
{% trans 'Parcels can not be calculated, since no geometry is given.' %} {% trans 'Parcels can not be calculated, since no geometry is given.' %}
</article> </article>
{% else %} {% else %}

@ -2,10 +2,19 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="card"> <div class="card">
<div class="card-header rlp-r"> <div class="card-header rlp-r">
<h5> <div class="row">
{% fa5_icon 'search-location' %} <div class="col-6">
{% trans 'Spatial reference' %} <h5>
</h5> {% fa5_icon 'search-location' %}
{% trans 'Spatial reference' %}
</h5>
</div>
<div class="col-6 text-right">
<h5>
{{ obj.geometry.geom.area|floatformat:2 }} m²
</h5>
</div>
</div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div hx-trigger="load, every 5s" hx-get="{% url 'geometry-parcels' geom_form.instance.geometry.id %}"> <div hx-trigger="load, every 5s" hx-get="{% url 'geometry-parcels' geom_form.instance.geometry.id %}">

@ -7,11 +7,14 @@ Created on: 25.11.20
""" """
from django.core.paginator import PageNotAnInteger, EmptyPage from django.core.paginator import PageNotAnInteger, EmptyPage
from django.db.models import F
from django.http import HttpRequest from django.http import HttpRequest
from django.template.loader import render_to_string
from django.utils.html import format_html from django.utils.html import format_html
import django_tables2 as tables import django_tables2 as tables
from django.utils.translation import gettext_lazy as _
from konova.models import BaseObject from konova.models import BaseObject, GeoReferencedMixin, ShareableObjectMixin
from konova.settings import PAGE_SIZE_DEFAULT, PAGE_PARAM, RESULTS_PER_PAGE_PARAM, PAGE_SIZE_OPTIONS from konova.settings import PAGE_SIZE_DEFAULT, PAGE_PARAM, RESULTS_PER_PAGE_PARAM, PAGE_SIZE_OPTIONS
@ -173,4 +176,56 @@ class TableRenderMixin:
max_length = 75 max_length = 75
if len(value) > max_length: if len(value) > max_length:
value = f"{value[:max_length]}..." value = f"{value[:max_length]}..."
return value return value
def render_d(self, value, record: GeoReferencedMixin):
""" Renders the parcel district column
Args:
value (str): The intervention geometry
record (GeoReferencedMixin): The record
Returns:
"""
parcels = value.get_underlying_parcels().values_list(
"parcel_group__name",
flat=True
).distinct()
html = render_to_string(
"table/gmrkng_col.html",
{
"entries": parcels,
"geometry": record.geometry
}
)
return html
def render_e(self, value, record: ShareableObjectMixin):
""" Renders the editable column
Args:
value (str): The identifier value
record (ShareableObjectMixin): The record
Returns:
"""
html = ""
has_access = record.is_shared_with(self.user)
html += self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
)
return format_html(html)
class TableOrderMixin:
"""
Holds different order_by methods for general purposes
"""
def order_lm(self, queryset, is_asc):
queryset = queryset.order_by(F('modified__timestamp').desc(nulls_last=True))
return (queryset, is_asc)

@ -6,6 +6,7 @@ Created on: 19.08.22
""" """
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.http import HttpRequest from django.http import HttpRequest
from django.shortcuts import render from django.shortcuts import render
from django.utils import timezone from django.utils import timezone
@ -50,22 +51,22 @@ def home_view(request: HttpRequest):
) )
# Then fetch only user related ones # Then fetch only user related ones
user_interventions = interventions.filter( user_interventions = interventions.filter(
users__in=[user] Q(users__in=[user]) | Q(teams__in=user.shared_teams)
) ).distinct()
# Repeat for other objects # Repeat for other objects
comps = Compensation.objects.filter( comps = Compensation.objects.filter(
deleted=None, deleted=None,
) )
user_comps = comps.filter( user_comps = comps.filter(
intervention__users__in=[user] Q(intervention__users__in=[user]) | Q(intervention__teams__in=user.shared_teams)
) ).distinct()
eco_accs = EcoAccount.objects.filter( eco_accs = EcoAccount.objects.filter(
deleted=None, deleted=None,
) )
user_ecco_accs = eco_accs.filter( user_ecco_accs = eco_accs.filter(
users__in=[user] Q(users__in=[user]) | Q(teams__in=user.shared_teams)
) ).distinct()
additional_context = { additional_context = {
"msgs": msgs, "msgs": msgs,

@ -1,4 +1,4 @@
{% load i18n %} {% load i18n fontawesome_5 %}
{% comment %} {% comment %}
Encapsules the rendering and initializing of a geometry view component, e.g. used in the detail views. Encapsules the rendering and initializing of a geometry view component, e.g. used in the detail views.
@ -6,7 +6,10 @@
{% if geom_form.empty %} {% if geom_form.empty %}
<div class="w-100"> <div class="w-100">
<div class="alert alert-info">{% trans 'No geometry added, yet.' %}</div> <div class="alert alert-info">
{% fa5_icon 'search-location' %}
{% trans 'No geometry added, yet.' %}
</div>
</div> </div>
{% endif %} {% endif %}

@ -1,9 +1,16 @@
{% load i18n fontawesome_5 %} {% load i18n fontawesome_5 %}
{% for entry in entries %} {% if geometry.geom is None or geometry.geom.empty %}
<span class="badge pill-badge rlp-r">{{entry}}</span> <span class="text-info" title="{% translate 'No geometry added, yet.' %}">
{% empty %} {% fa5_icon 'search-location' %}
<span class="text-info" title="{% trans 'If the geometry is not empty, the parcels are currently recalculated. Please refresh this page in a few moments.' %}"> {% fa5_icon 'question' %}
{% fa5_icon 'hourglass-half' %}
</span> </span>
{% endfor %} {% else %}
{% for entry in entries %}
<span class="badge pill-badge rlp-r">{{entry}}</span>
{% empty %}
<span class="text-info" title="{% trans 'If the geometry is not empty, the parcels are currently recalculated. Please refresh this page in a few moments.' %}">
{% fa5_icon 'hourglass-half' %}
</span>
{% endfor %}
{% endif %}

@ -38,14 +38,6 @@
</article> </article>
<hr> <hr>
<div class="col-sm"> <div class="col-sm">
<div class="row mb-2">
<a href="{% url 'user:index' %}" title="{% trans 'Change default configuration for your KSP map' %}">
<button class="btn btn-default">
{% fa5_icon 'layer-group' %}
<span>{% trans 'Map settings' %}</span>
</button>
</a>
</div>
<div class="row mb-2"> <div class="row mb-2">
<a href="{% url 'user:notifications' %}" title="{% trans 'Change notification configurations' %}"> <a href="{% url 'user:notifications' %}" title="{% trans 'Change notification configurations' %}">
<button class="btn btn-default"> <button class="btn btn-default">

Loading…
Cancel
Save