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,
|
||||
GovernmentPlanSection,
|
||||
GovernmentPlanSectionsCMSPlugin,
|
||||
GovernmentPlanUpdatesCMSPlugin,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -51,3 +52,18 @@ class GovernmentPlanSectionsPlugin(CMSPluginBase):
|
|||
context["sections"] = sections
|
||||
|
||||
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
|
||||
]
|
||||
|
||||
def get_section(self):
|
||||
return GovernmentPlanSection.objects.filter(
|
||||
categories__in=self.categories.all()
|
||||
).first()
|
||||
|
||||
def update_from_updates(self):
|
||||
last_status_update = (
|
||||
self.updates.all().filter(public=True).exclude(status="").first()
|
||||
|
|
@ -507,3 +512,58 @@ if CMSPlugin:
|
|||
government = models.ForeignKey(
|
||||
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 class="row">
|
||||
{% for update in updates %}
|
||||
<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 %}
|
||||
{% include "froide_govplan/plugins/updates.html" with wrapper_classes="col col-12 col-lg-6 d-flex mb-4" %}
|
||||
|
||||
{% if update.foirequest %}
|
||||
<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="col col-12 col-lg-6 d-flex mb-4">
|
||||
<div class="box-card border-gray shadow-gray">
|
||||
<div>
|
||||
<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"
|
||||
)
|
||||
|
||||
def get_section(self):
|
||||
return GovernmentPlanSection.objects.filter(
|
||||
categories__in=self.object.categories.all()
|
||||
).first()
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["updates"] = self.object.updates.filter(public=True).order_by(
|
||||
"-timestamp"
|
||||
)
|
||||
context["section"] = self.get_section()
|
||||
context["section"] = self.object.get_section()
|
||||
if self.request.user.is_authenticated:
|
||||
context["update_proposal_form"] = GovernmentPlanUpdateProposalForm()
|
||||
# For CMS toolbar
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue