add updates plugin

This commit is contained in:
krmax44 2022-03-17 16:38:47 +01:00
parent ca79e88c16
commit 03342fde2d
No known key found for this signature in database
GPG key ID: 5C499A4F4EC4EE03
6 changed files with 162 additions and 40 deletions

View file

@ -8,6 +8,7 @@ from .models import (
GovernmentPlansCMSPlugin, GovernmentPlansCMSPlugin,
GovernmentPlanSection, GovernmentPlanSection,
GovernmentPlanSectionsCMSPlugin, GovernmentPlanSectionsCMSPlugin,
GovernmentPlanUpdatesCMSPlugin,
) )
@ -51,3 +52,18 @@ class GovernmentPlanSectionsPlugin(CMSPluginBase):
context["sections"] = sections context["sections"] = sections
return context return context
@plugin_pool.register_plugin
class GovernmentPlanUpdatesPlugin(CMSPluginBase):
name = _("Government plan updates")
model = GovernmentPlanUpdatesCMSPlugin
render_template = "froide_govplan/plugins/updates.html"
def render(self, context, instance, placeholder):
context = super().render(context, instance, placeholder)
context["updates"] = instance.get_updates(
context["request"], published_only=False
)
context["show_context"] = True
return context

View file

@ -0,0 +1,30 @@
# Generated by Django 3.2.12 on 2022-03-17 14:54
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cms', '0022_auto_20180620_1551'),
('publicbody', '0039_publicbody_alternative_emails'),
('froide_govplan', '0008_governmentplan_proposals'),
]
operations = [
migrations.CreateModel(
name='GovernmentPlanUpdatesCMSPlugin',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='froide_govplan_governmentplanupdatescmsplugin', serialize=False, to='cms.cmsplugin')),
('count', models.PositiveIntegerField(default=1, help_text='0 means all the updates', verbose_name='number of updates')),
('offset', models.PositiveIntegerField(default=0, help_text='number of updates to skip from top of list', verbose_name='offset')),
('categories', models.ManyToManyField(blank=True, to='publicbody.Category', verbose_name='categories')),
('government', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='froide_govplan.government')),
],
options={
'abstract': False,
},
bases=('cms.cmsplugin',),
),
]

View file

@ -220,6 +220,11 @@ class GovernmentPlan(models.Model):
"{}#p-{}".format(self.government.planning_document, ref) for ref in refs "{}#p-{}".format(self.government.planning_document, ref) for ref in refs
] ]
def get_section(self):
return GovernmentPlanSection.objects.filter(
categories__in=self.categories.all()
).first()
def update_from_updates(self): def update_from_updates(self):
last_status_update = ( last_status_update = (
self.updates.all().filter(public=True).exclude(status="").first() self.updates.all().filter(public=True).exclude(status="").first()
@ -507,3 +512,58 @@ if CMSPlugin:
government = models.ForeignKey( government = models.ForeignKey(
Government, null=True, blank=True, on_delete=models.SET_NULL Government, null=True, blank=True, on_delete=models.SET_NULL
) )
class GovernmentPlanUpdatesCMSPlugin(CMSPlugin):
"""
CMS Plugin for displaying plan updates
"""
government = models.ForeignKey(
Government, null=True, blank=True, on_delete=models.SET_NULL
)
categories = models.ManyToManyField(
Category, verbose_name=_("categories"), blank=True
)
count = models.PositiveIntegerField(
_("number of updates"), default=1, help_text=_("0 means all the updates")
)
offset = models.PositiveIntegerField(
_("offset"),
default=0,
help_text=_("number of updates to skip from top of list"),
)
def get_updates(self, request, published_only=True):
# TODO: remove duplication with GovernmentPlansCMSPlugin.get_plans
if (
published_only
or not request
or not getattr(request, "toolbar", False)
or not request.toolbar.edit_mode_active
):
updates = GovernmentPlanUpdate.objects.filter(public=True)
else:
updates = GovernmentPlanUpdate.objects.all()
updates = updates.order_by("-timestamp").prefetch_related(
"plan", "plan__categories"
)
filters = {}
if self.government_id:
filters["plan__government_id"] = self.government_id
cat_list = self.categories.all().values_list("id", flat=True)
if cat_list:
filters["plan__categories__in"] = cat_list
updates = updates.filter(**filters).distinct()
if self.count == 0:
return updates[self.offset :]
return updates[self.offset : self.offset + self.count]
def __str__(self):
if self.count == 0:
return str(_("All matching updates"))
return _("%s matching updates") % self.count

View file

@ -159,41 +159,9 @@
</div> </div>
<div class="row"> <div class="row">
{% for update in updates %} {% include "froide_govplan/plugins/updates.html" with wrapper_classes="col col-12 col-lg-6 d-flex mb-4" %}
<div class="col col-12 col-lg-6 d-flex mb-3" id="update-{{ update.pk }}">
<div class="box-card border-blue shadow-blue">
<div>
<a href="#update-{{ update.pk }}" class="text-body text-decoration-none">
<div class="box-card-header bg-blue-20 d-flex justify-content-center p-3 p-md-4 tight-margin flex-column">
<h3 class="h4">{{ update.title }}</h3>
<div class="d-md-flex small">
<time datetime="{{ update.timestamp|date:'c' }}">{{ update.timestamp|date:"DATE_FORMAT" }}</time>
<p class="m-0 ml-auto">{% if update.user %}von {{ update.user.get_full_name }}{% endif %}{% if update.organization %}, {{ update.organization.name }}{% endif %}</p>
</div>
</div>
</a>
{% if update.content %}
<div class="p-3 p-md-4 tight-margin">
{{ update.content|markdown }}
</div>
{% endif %}
</div>
{% if update.url or update.foirequest %}
<div class="p-3 p-md-4 {% if update.content %}box-card-links{% else %}d-flex mt-auto{% endif %}">
{% if update.url %}
<a href="{{ update.url }}" class="action-link mr-3">→ Mehr auf {{ update.get_url_domain }} lesen…</a>
{% endif %}
{% if update.foirequest %} <div class="col col-12 col-lg-6 d-flex mb-4">
<a href="{{ update.foirequest.get_absolute_url }}" class="action-link">→ zur Anfrage</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
{% endfor %}
<div class="col col-12 col-lg-6 d-flex mb-3">
<div class="box-card border-gray shadow-gray"> <div class="box-card border-gray shadow-gray">
<div> <div>
<div class="box-card-header bg-gray-200 d-flex justify-content-center p-3 p-md-4 tight-margin flex-column"> <div class="box-card-header bg-gray-200 d-flex justify-content-center p-3 p-md-4 tight-margin flex-column">

View file

@ -0,0 +1,53 @@
{% load markup %}
{% for update in updates %}
<div class="{{ wrapper_classes }}">
<div class="box-card border-blue shadow-blue" id="update-{{ update.pk }}">
<div>
<a href="{{ update.get_absolute_url }}" class="text-body text-decoration-none">
<div class="box-card-header bg-blue-20 d-flex justify-content-center p-3 p-md-4 tight-margin flex-column">
<div class="d-md-flex">
{% if show_context %}
<div class="order-2 ml-auto">
<span class="badge badge-blue-100 badge-pill mb-2">
{{ update.plan.get_section }}
</span>
</div>
{% endif %}
<h3 class="h4 mt-0">
{% if show_context %}
{{ update.plan }}
{% else %}
{{ update.title }}
{% endif %}
</h3>
</div>
<div class="small">
<time datetime="{{ update.timestamp|date:'c' }}">{{ update.timestamp|date:"DATE_FORMAT" }}</time>
<span>{% if update.user %}von {{ update.user.get_full_name }}{% endif %}{% if update.organization %}, {{ update.organization.name }}{% endif %}</span>
</div>
</div>
</a>
{% if update.content %}
<div class="p-3 p-md-4 tight-margin">
{% if show_context %}
<h4 class="h5">{{ update.title }}</h4>
{% endif %}
{{ update.content|markdown }}
</div>
{% endif %}
</div>
{% if update.url or update.foirequest %}
<div class="p-3 p-md-4 {% if update.content %}box-card-links{% else %}d-flex mt-auto{% endif %}">
{% if update.url %}
<a href="{{ update.url }}" class="action-link mr-3" target="_blank" rel="noopener">→ Mehr auf {{ update.get_url_domain }} lesen…</a>
{% endif %}
{% if update.foirequest %}
<a href="{{ update.foirequest.get_absolute_url }}" class="action-link">→ zur Anfrage</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
{% endfor %}

View file

@ -53,17 +53,12 @@ class GovPlanDetailView(GovernmentMixin, DetailView):
"responsible_publicbody", "organization" "responsible_publicbody", "organization"
) )
def get_section(self):
return GovernmentPlanSection.objects.filter(
categories__in=self.object.categories.all()
).first()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context["updates"] = self.object.updates.filter(public=True).order_by( context["updates"] = self.object.updates.filter(public=True).order_by(
"-timestamp" "-timestamp"
) )
context["section"] = self.get_section() context["section"] = self.object.get_section()
if self.request.user.is_authenticated: if self.request.user.is_authenticated:
context["update_proposal_form"] = GovernmentPlanUpdateProposalForm() context["update_proposal_form"] = GovernmentPlanUpdateProposalForm()
# For CMS toolbar # For CMS toolbar