add updates plugin
This commit is contained in:
parent
ca79e88c16
commit
03342fde2d
6 changed files with 162 additions and 40 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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',),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
53
froide_govplan/templates/froide_govplan/plugins/updates.html
Normal file
53
froide_govplan/templates/froide_govplan/plugins/updates.html
Normal 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 %}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue