Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Release] Linha do Tempo e App Publicações Site Nossas #189

Merged
merged 31 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
19219ad
feat(nossas): init publications app
igr-santos Mar 18, 2024
643ef63
chore(nossas): refactor import to page select2 field
igr-santos Mar 18, 2024
346d70b
feat(nossas): add page to detail publication
igr-santos Mar 19, 2024
68fd077
fix(nossas): change footer text
igr-santos Mar 19, 2024
dbe8698
feat(nossas): add haystack to implement search publications and campa…
igr-santos Mar 20, 2024
4a2cb54
chore: add badge to build image docker
igr-santos Mar 20, 2024
9a5d059
Merge branch 'main' into feature/publications-app
igr-santos Mar 22, 2024
0fac1b0
feat(nossas): add external_link to publication
igr-santos Mar 28, 2024
d46a3fd
feat(nossas): add plugin to list publications by category/page
igr-santos Mar 28, 2024
d3c03e7
fix(nossas): add js for filtering in user's select order
miguelzinh3 Mar 12, 2024
fda2860
fix(nossas): change group and release year to multiple on filter camp…
igr-santos Mar 14, 2024
a7e6d6c
Merge pull request #191 from nossas/feature/publications-app
miguelzinh3 Apr 1, 2024
cc92aac
fix(nossas): add css classes to footer plugin
miguelzinh3 Mar 14, 2024
ade5728
fix(nossas): change max width to footer menu item
igr-santos Mar 15, 2024
e6391ca
feat(nossas): add timeline app structure
miguelzinh3 Mar 15, 2024
49a91f2
feat(nossas): add TimelineEventContext model
miguelzinh3 Mar 20, 2024
f985366
feat(nossas): add events_world and events_nossas into list template
miguelzinh3 Mar 21, 2024
e4ee611
feat(nossas): add styles to timeline plugin
miguelzinh3 Mar 22, 2024
a542b02
feat(nossas): add order by unique year-month func in timeline plugin
miguelzinh3 Mar 25, 2024
4923f58
feat(nossas): add timeline styles (dots and other symbols)
miguelzinh3 Mar 26, 2024
003c7cb
feat(nossas): add year filter to timeline plugin
miguelzinh3 Mar 27, 2024
1273f38
fix(nossas): remove timeline apphook
miguelzinh3 Mar 28, 2024
d24cbf1
Merge pull request #190 from nossas/feature/app-timeline
miguelzinh3 Apr 1, 2024
8721890
feat(nossas): add input widget to count chars
igr-santos Apr 3, 2024
4401d6f
fix(nossas): render empty lists and add limit to description chars
igr-santos Apr 3, 2024
938a0b2
chore(nossas): change location to template plugins
igr-santos Apr 3, 2024
2e04cc8
fix(nossas): size select filter timeline
igr-santos Apr 3, 2024
46016ee
feat(nossas): become text on timeline plugin editable with text plugin
igr-santos Apr 3, 2024
d0861c8
feat(nossas): add column size to mobile grid
igr-santos Apr 4, 2024
1b74636
fix(nossas): filter categories to add Publication admin
igr-santos Apr 8, 2024
21b2a23
fix(nossas): change help texts to grid plugin
igr-santos Apr 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![Publish Bonde CMS docker image](https://github.com/nossas/cms/actions/workflows/publish.yml/badge.svg?branch=main)](https://github.com/nossas/cms/actions/workflows/publish.yml)

Bonde CMS
----------

Expand Down
3 changes: 2 additions & 1 deletion app/nossas/apps/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .campaigns import *
from .institutional import *
from .jobs import *
from .teams import *
from .teams import *
from .timeline import *
27 changes: 27 additions & 0 deletions app/nossas/apps/admin/timeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from django.contrib import admin
from ..models.timeline import TimelineEvent

from nossas.apps.baseadmin import OnSiteAdmin
from ..forms.timeline import TimelineEventForm


@admin.register(TimelineEvent)
class TimelineEventAdmin(OnSiteAdmin):
list_display = ("title", "month", "year", "image")
list_filter = ("year", "month")
search_fields = ("title", "description")
form = TimelineEventForm
fieldsets = (
(
None,
{
"fields": [
"event_context",
("day", "month", "year"),
"title",
"description",
"image",
],
},
),
)
2 changes: 2 additions & 0 deletions app/nossas/apps/basemodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class OnSiteBaseModel(models.Model):
site = models.ForeignKey(Site, on_delete=models.CASCADE)

on_site = CurrentSiteManager()
# Force objects queryset
objects = CurrentSiteManager()

class Meta:
abstract = True
2 changes: 1 addition & 1 deletion app/nossas/apps/cms_apps/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .campaigns import *
from .jobs import *
from .jobs import *
1 change: 1 addition & 0 deletions app/nossas/apps/cms_plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .campaigns import *
from .jobs import *
from .teams import *
from .timeline import *
5 changes: 3 additions & 2 deletions app/nossas/apps/cms_plugins/campaigns.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,18 @@ def render(self, context, instance, placeholder):

if form.is_valid():
filters = {}

release_year = form.cleaned_data.get("release_year")
if release_year:
filters["release_date__year"] = release_year
filters["release_date__year__in"] = release_year

tags = form.cleaned_data.get("tags")
if tags:
filters["tags__slug__in"] = tags

campaign_group_id = form.cleaned_data.get("campaign_group_id")
if campaign_group_id:
filters["campaign_group__id"] = campaign_group_id
filters["campaign_group__id__in"] = campaign_group_id

if (
settings.DATABASES.get("default").get("ENGINE")
Expand Down
126 changes: 126 additions & 0 deletions app/nossas/apps/cms_plugins/timeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
from itertools import zip_longest
from collections import defaultdict

from cms.api import add_plugin
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool

from ..forms.timeline import TimelineFilterForm
from ..models.timeline import TimelineEvent


@plugin_pool.register_plugin
class TimelinePlugin(CMSPluginBase):
name = "Linha do Tempo"
module = "NOSSAS"
render_template = "plugins/timeline_plugin.html"
allow_children = True
child_classes = ["TextPlugin"]

def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)

if not change:
placeholder = obj.placeholder
language = obj.language

# Child plugins
# Text Plugin
plugin_type = "TextPlugin"
child_attrs = {
"body": f"""<p>Siga a linha do tempo e entenda a atuação do NOSSAS ao longo dos anos. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed qut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut a quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae.</p>"""
}

add_plugin(
placeholder=placeholder,
plugin_type=plugin_type,
language=language,
target=obj,
**child_attrs,
)

def prepare_timeline_events(self, events_world, events_nossas):
# Organiza eventos por ano e mês
events_by_year_month_world = defaultdict(lambda: defaultdict(list))
events_by_year_month_nossas = defaultdict(lambda: defaultdict(list))

for event in events_world:
events_by_year_month_world[event.year][event.month].append(event)

for event in events_nossas:
events_by_year_month_nossas[event.year][event.month].append(event)

unique_years_months = set(events_by_year_month_world.keys()) | set(
events_by_year_month_nossas.keys()
)
for year in unique_years_months:
months_world = set(events_by_year_month_world[year].keys())
months_nossas = set(events_by_year_month_nossas[year].keys())
all_months = months_world | months_nossas

for month in sorted(all_months):
if month not in months_world:
events_by_year_month_world[year][month] = []
if month not in months_nossas:
events_by_year_month_nossas[year][month] = []

sorted_events_world = sorted(
[
(year, month, events_by_year_month_world[year][month])
for year in events_by_year_month_world
for month in sorted(events_by_year_month_world[year])
],
key=lambda x: (x[0], x[1]),
)
sorted_events_nossas = sorted(
[
(year, month, events_by_year_month_nossas[year][month])
for year in events_by_year_month_nossas
for month in sorted(events_by_year_month_nossas[year])
],
key=lambda x: (x[0], x[1]),
)

# Mantem os eventos alinhados entre as categorias
aligned_events_world, aligned_events_nossas = zip(
*zip_longest(
sorted_events_world, sorted_events_nossas, fillvalue=(None, None, [])
)
)

return aligned_events_world, aligned_events_nossas

def render(self, context, instance, placeholder):
context = super().render(context, instance, placeholder)
request = context.get("request")
form = TimelineFilterForm(request.GET)
event_filter = {}

if form.is_valid():
year = form.cleaned_data["year"]
if year:
event_filter.update({"year": year})

events_world = TimelineEvent.on_site.filter(
event_context="mundo", **event_filter
).order_by("year", "month", "day")
events_nossas = TimelineEvent.on_site.filter(
event_context="nossas", **event_filter
).order_by("year", "month", "day")

if len(events_nossas) > 0 and len(events_world) > 0:
aligned_events_world, aligned_events_nossas = self.prepare_timeline_events(
events_world, events_nossas
)
else:
aligned_events_world, aligned_events_nossas = [], []

context.update(
{
"aligned_events_world": aligned_events_world,
"aligned_events_nossas": aligned_events_nossas,
"form": form,
}
)

return context
8 changes: 4 additions & 4 deletions app/nossas/apps/forms/campaigns.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ class CampaignFilterForm(forms.Form):
widget=s2forms.Select2MultipleWidget(),
required=False,
)
campaign_group_id = forms.ChoiceField(
campaign_group_id = forms.MultipleChoiceField(
label=_("Cidade"),
choices=lazy(get_campaign_groups, tuple)(),
widget=s2forms.Select2Widget,
widget=s2forms.Select2MultipleWidget(),
required=False,
)
release_year = forms.ChoiceField(
release_year = forms.MultipleChoiceField(
label=_("Ano"),
choices=lazy(get_release_years, tuple)(),
widget=s2forms.Select2Widget,
widget=s2forms.Select2MultipleWidget(),
required=False,
)
35 changes: 35 additions & 0 deletions app/nossas/apps/forms/timeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from django import forms
from django.utils.functional import lazy
from django.utils.translation import gettext_lazy as _

from nossas.design.widgets import CharsLeftTextInput, CharsLeftTextarea

from ..models.timeline import TimelineEvent

def get_events_year_choices():
years = TimelineEvent.on_site.order_by('-year').values_list('year', flat=True).distinct()
return [((year), year) for year in years]

class TimelineFilterForm(forms.Form):
year = forms.ChoiceField(
label=_("Ano"),
choices=lazy(get_events_year_choices, list)(),
widget=forms.Select(attrs={
"class": "selectpicker",
"title": "Selecione um ano",
"data-width": "fit",
"data-allow-clear": "true"
}),
required=False,
)



class TimelineEventForm(forms.ModelForm):

class Meta:
model = TimelineEvent
fields = "__all__"
widgets = {
"description": CharsLeftTextarea(attrs={"maxlength": 200})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Generated by Django 4.2 on 2024-03-18 17:48

from django.conf import settings
import django.contrib.sites.managers
from django.db import migrations, models
import django.db.models.deletion
import filer.fields.image


class Migration(migrations.Migration):

dependencies = [
('sites', '0002_alter_domain_unique'),
migrations.swappable_dependency(settings.FILER_IMAGE_MODEL),
('apps', '0014_navigatecampaigns_related_campaigns_and_more'),
]

operations = [
migrations.AlterField(
model_name='navigatecampaigns',
name='related_campaigns',
field=models.ManyToManyField(blank=True, help_text='Caso não queira o preenchimento automático das Campanhas, você deve selecionar nesse campo as Campanhas que deseja mostrar.', related_name='related_campaigns_navigate_campaigns_plugin', to='apps.campaign', verbose_name='Campanhas relacionadas'),
),
migrations.CreateModel(
name='TimelineEvent',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('month', models.CharField(max_length=20, verbose_name='Mês')),
('year', models.IntegerField(verbose_name='Ano')),
('title', models.CharField(max_length=255, verbose_name='Título')),
('description', models.TextField(verbose_name='Descrição')),
('image', filer.fields.image.FilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='timeline_images', to=settings.FILER_IMAGE_MODEL, verbose_name='Imagem')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.site')),
],
options={
'verbose_name': 'Evento da Timeline',
'verbose_name_plural': 'Eventos da Timeline',
'ordering': ['-year', '-month'],
},
managers=[
('on_site', django.contrib.sites.managers.CurrentSiteManager()),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Generated by Django 4.2 on 2024-03-20 17:10

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('apps', '0015_alter_navigatecampaigns_related_campaigns_and_more'),
]

operations = [
migrations.AlterModelOptions(
name='timelineevent',
options={'ordering': ['-year', '-month', '-day'], 'verbose_name': 'Evento da Timeline', 'verbose_name_plural': 'Eventos da Timeline'},
),
migrations.AddField(
model_name='timelineevent',
name='day',
field=models.IntegerField(default=1, verbose_name='Dia'),
),
migrations.AddField(
model_name='timelineevent',
name='event_context',
field=models.CharField(choices=[('mundo', 'Mundo'), ('nossas', 'Nossas')], default='mundo', max_length=6),
),
migrations.AlterField(
model_name='timelineevent',
name='month',
field=models.IntegerField(default=1, verbose_name='Mês'),
),
migrations.AlterField(
model_name='timelineevent',
name='title',
field=models.CharField(max_length=140, verbose_name='Título'),
),
migrations.AlterField(
model_name='timelineevent',
name='year',
field=models.IntegerField(default=2024, verbose_name='Ano'),
),
]
3 changes: 2 additions & 1 deletion app/nossas/apps/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .campaigns import *
from .institutional import *
from .jobs import *
from .teams import *
from .teams import *
from .timeline import *
4 changes: 4 additions & 0 deletions app/nossas/apps/models/campaigns.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ def __str__(self):
def get_absolute_url(self):
return reverse("campaigns:campaign-detail", kwargs={"pk": self.pk})

@property
def get_pub_date(self):
return self.release_date

def create_default_page(self):
language = "pt-br"

Expand Down
Loading
Loading