Skip to content

Commit

Permalink
module-tiles: add sorting and grid for module tiles
Browse files Browse the repository at this point in the history
  • Loading branch information
vellip authored and m4ra committed Feb 18, 2025
1 parent 3725b35 commit 7cedc7e
Show file tree
Hide file tree
Showing 17 changed files with 92 additions and 120 deletions.
3 changes: 3 additions & 0 deletions changelog/8874.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Added
- Grid view for module tiles
- template tag for sorting modules into: running, upcoming, ended
4 changes: 0 additions & 4 deletions meinberlin/apps/plans/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ class Plan(ProjectContactDetailMixin, UserGeneratedContentModel):
verbose_name=_("Title of your plan"),
)

@property
def name(self):
return self.title

organisation = models.ForeignKey(
settings.A4_ORGANISATIONS_MODEL,
on_delete=models.CASCADE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<h1 class="u-first-heading">{% translate 'Participation is not possible at the moment.' %}</h1>
<p>
{% html_date project.modules.first.future_phases.first.start_date 'DATE_FORMAT' as start_date %}
{% blocktranslate with date=start_date %}It starts on {{ date }}.{% endblocktrans %}
{% blocktranslate with date=start_date %}It starts on {{ date }}.{% endblocktranslate %}
</p>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,28 +90,16 @@ <h4 class="my-0">{{ event.name }}</h4>
{% endfor %}
</ul>
</article>
{% elif view.is_project_view %}
<ul class="list--clean">
{% for module in modules %}
<li>
{% include "meinberlin_projects/includes/project_module_tile.html" with project=project module=module %}
</li>
{% endfor %}
</ul>
{% else %}
<!-- if just one module and no phase view to dispatch to -->
<div class="modul-servicepanel fullwidth panel--heavy phase-info">
<div class="servicepanel__main">
{% include "a4modules/includes/module_detail_phase.html" %}
</div>
<!-- these blocks are only filled when in phase view -->
<div class="servicepanel__right phase-info__cta">
{% block project_action %}{% endblock project_action %}
</div>
</div>
{% endif %}
{% block voting_token_field %}{% endblock voting_token_field %}
{% block phase_content %}{% endblock phase_content %}
<h2>{% translate "Online Participation" %}</h2>
<ul class="list--clean flexgrid grid--3">
{% get_sorted_modules as modules %}
{% for module in modules %}
<li>
{% include "meinberlin_projects/includes/project_module_tile.html" with project=project module=module %}
</li>
{% endfor %}
</ul>
</section>
<section aria-labelledby="tab-project-{{ project.pk }}-result">
<h2 class="mt-0" id="tab-project-{{ project.pk }}-result">{% translate "Result" %}</h2>
Expand Down
20 changes: 20 additions & 0 deletions meinberlin/apps/projects/templatetags/meinberlin_project_tags.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import itertools

from django import template
from django.db.models import Count
from django.db.models import Q
Expand Down Expand Up @@ -33,6 +35,24 @@ def is_external(project):
)


@register.simple_tag(takes_context=True)
def get_sorted_modules(context):
project = context["project"]
module = context.get("module", None)
module_qs = project.modules

if module:
module_qs = module.other_modules

return list(
itertools.chain(
module_qs.running_modules(),
module_qs.future_modules(),
module_qs.past_modules(),
)
)


@register.simple_tag
def get_num_entries(module):
"""Count all user-generated items."""
Expand Down
14 changes: 5 additions & 9 deletions meinberlin/apps/projects/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@
from adhocracy4.filters.widgets import DropdownLinkWidget
from adhocracy4.modules import models as module_models
from adhocracy4.projects import models as project_models
from adhocracy4.projects.mixins import DisplayProjectOrModuleMixin
from adhocracy4.projects.mixins import PhaseDispatchMixin
from adhocracy4.projects.mixins import ProjectMixin
from adhocracy4.projects.mixins import ProjectModuleDispatchMixin
from meinberlin.apps.offlineevents.models import OfflineEvent

from . import forms
Expand Down Expand Up @@ -339,9 +337,7 @@ def get_permission_object(self):
return self.project


class ProjectDetailView(
PermissionRequiredMixin, ProjectModuleDispatchMixin, DisplayProjectOrModuleMixin
):
class ProjectDetailView(PermissionRequiredMixin, generic.DetailView):
model = models.Project
permission_required = "a4projects.view_project"

Expand All @@ -353,14 +349,14 @@ def get_template_names(self):
return ["meinberlin_projects/project_bplan_detail.html"]
return ["meinberlin_projects/project_detail.html"]

@cached_property
def is_project_view(self):
return self.get_current_modules()

@property
def raise_exception(self):
return self.request.user.is_authenticated

@cached_property
def project(self):
return self.get_object()

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["events"] = self.project.offlineevent_set.all().order_by("date")
Expand Down
23 changes: 10 additions & 13 deletions meinberlin/templates/a4modules/module_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,16 @@ <h1>
{% block voting_token_field %}{% endblock voting_token_field %}
{% block phase_content %}{% endblock phase_content %}
{% if module.is_in_module_cluster %}
<section class="participation-tile__wrapper">
<div class="participation-tile__list-container">
<h2 class="participation-tile__list-header">{% translate 'More from this online participation:' %}</h2>
<ul class="u-list-reset participation-tile__list">
{% for other_module in module.module_cluster %}
{% if not other_module == module %}
<li>
{% include "meinberlin_projects/includes/project_module_tile.html" with project=project module=other_module %}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
<section>
<h2>{% translate 'More from this online participation:' %}</h2>
<ul class="list--clean flexgrid grid--3">
{% get_sorted_modules as modules %}
{% for module in modules %}
<li>
{% include "meinberlin_projects/includes/project_module_tile.html" with project=project module=module %}
</li>
{% endfor %}
</ul>
</section>
{% endif %}
</section>
Expand Down
8 changes: 4 additions & 4 deletions tests/bplan/test_views_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_statement_form_view(client, phase_factory, bplan_factory, module_factor
bplan = bplan_factory(is_draft=False)
module = module_factory(project=bplan)
phase = phase_factory(phase_content=phases.StatementPhase(), module=module)
url = bplan.get_absolute_url()
url = module.get_absolute_url()
with freeze_phase(phase):
response = client.get(url)
assert_template_response(
Expand All @@ -39,7 +39,7 @@ def test_statement_form_view_no_captcha(
bplan = bplan_factory(is_draft=False)
module = module_factory(project=bplan)
phase = phase_factory(phase_content=phases.StatementPhase(), module=module)
url = bplan.get_absolute_url()
url = module.get_absolute_url()
with freeze_phase(phase):
response = client.get(url)
assert_template_response(
Expand All @@ -65,7 +65,7 @@ def test_statement_emails(client, phase_factory, bplan_factory, module_factory):
bplan = bplan_factory(is_draft=False)
module = module_factory(project=bplan)
phase = phase_factory(phase_content=phases.StatementPhase(), module=module)
url = bplan.get_absolute_url()
url = module.get_absolute_url()
with freeze_phase(phase):
response = client.get(url)
assert_template_response(
Expand Down Expand Up @@ -101,7 +101,7 @@ def test_statement_form_view_post_phase(
bplan = bplan_factory(is_draft=False)
module = module_factory(project=bplan)
phase = phase_factory(phase_content=phases.StatementPhase(), module=module)
url = bplan.get_absolute_url()
url = module.get_absolute_url()
with freeze_post_phase(phase):
response = client.get(url)
assert response.status_code == 302
Expand Down
41 changes: 29 additions & 12 deletions tests/budgeting/test_views_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,21 @@ def test_list_view(client, phase_factory, proposal_factory, area_settings_factor
phase_factory, proposal_factory, phases.RequestPhase
)
area_settings_factory(module=module)
url = project.get_absolute_url()
url = module.get_absolute_url()
with freeze_phase(phase):
response = client.get(url)
assert_template_response(response, "meinberlin_budgeting/proposal_list.html")


@pytest.mark.django_db
def test_list_view_qs_gets_annotated(client, phase_factory, proposal_factory, area_settings_factory):
def test_list_view_qs_gets_annotated(
client, phase_factory, proposal_factory, area_settings_factory
):
phase, module, project, proposal = setup_phase(
phase_factory, proposal_factory, phases.VotingPhase
)
area_settings_factory(module=module)
url = project.get_absolute_url()
url = module.get_absolute_url()

with freeze_phase(phase):
response = client.get(url)
Expand All @@ -45,12 +47,14 @@ def test_list_view_qs_gets_annotated(client, phase_factory, proposal_factory, ar


@pytest.mark.django_db
def test_list_view_ordering_choices(client, phase_factory, proposal_factory, area_settings_factory):
def test_list_view_ordering_choices(
client, phase_factory, proposal_factory, area_settings_factory
):
phase, module, project, item = setup_phase(
phase_factory, proposal_factory, phases.RatingPhase
)
area_settings_factory(module=module)
url = project.get_absolute_url()
url = module.get_absolute_url()
with freeze_phase(phase):
response = client.get(url)
view = response.context["view"]
Expand All @@ -66,7 +70,7 @@ def test_list_view_ordering_choices(client, phase_factory, proposal_factory, are
phase_factory, proposal_factory, phases.SupportPhase
)
area_settings_factory(module=module)
url = project.get_absolute_url()
url = module.get_absolute_url()
with freeze_phase(phase):
response = client.get(url)
view = response.context["view"]
Expand All @@ -80,7 +84,9 @@ def test_list_view_ordering_choices(client, phase_factory, proposal_factory, are


@pytest.mark.django_db
def test_list_view_default_filters(client, module, phase_factory, area_settings_factory):
def test_list_view_default_filters(
client, module, phase_factory, area_settings_factory
):
area_settings_factory(module=module)
support_phase = phase_factory(
phase_content=phases.SupportPhase(),
Expand Down Expand Up @@ -133,13 +139,19 @@ def test_list_view_default_filters(client, module, phase_factory, area_settings_

@pytest.mark.django_db
def test_list_view_token_form(
client, user, phase_factory, proposal_factory, voting_token_factory, module_factory, area_settings_factory
client,
user,
phase_factory,
proposal_factory,
voting_token_factory,
module_factory,
area_settings_factory,
):
phase, module, project, item = setup_phase(
phase_factory, proposal_factory, phases.VotingPhase
)
area_settings_factory(module=module)
url = project.get_absolute_url()
url = module.get_absolute_url()
token = voting_token_factory(module=module)

data = {"token": str(token)}
Expand Down Expand Up @@ -181,13 +193,18 @@ def test_list_view_token_form(

@pytest.mark.django_db
def test_list_view_token_form_redirect(
client, user, phase_factory, proposal_factory, voting_token_factory, area_settings_factory
client,
user,
phase_factory,
proposal_factory,
voting_token_factory,
area_settings_factory,
):
phase, module, project, item = setup_phase(
phase_factory, proposal_factory, phases.VotingPhase
)
area_settings_factory(module=module)
url = project.get_absolute_url()
url = module.get_absolute_url()
token = voting_token_factory(module=module)

data = {"token": str(token)}
Expand Down Expand Up @@ -354,7 +371,7 @@ def test_detail_view_token_in_session(
area_settings_factory(module=module_2)

token_1 = voting_token_factory(module=module_1)
project_url = project_1.get_absolute_url()
project_url = module_1.get_absolute_url()
data = {"token": str(token_1)}

proposal_1_url = proposal_1.get_absolute_url()
Expand Down
2 changes: 1 addition & 1 deletion tests/documents/test_views_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def test_document_detail_view(client, phase_factory, chapter_factory):
phase, module, project, item = setup_phase(
phase_factory, chapter_factory, phases.CommentPhase
)
url = project.get_absolute_url()
url = module.get_absolute_url()
with freeze_phase(phase):
response = client.get(url)
assert_template_response(response, "meinberlin_documents/chapter_detail.html")
Expand Down
6 changes: 3 additions & 3 deletions tests/ideas/views/test_idea_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def test_list_view(client, phase_factory, idea_factory):
phase_2, module_2, project_2, idea_2 = setup_phase(
phase_factory, idea_factory, phases.FeedbackPhase
)
url = project.get_absolute_url()
url = module.get_absolute_url()

with freeze_phase(phase):
response = client.get(url)
Expand All @@ -34,7 +34,7 @@ def test_list_view_qs_gets_annotated(client, phase_factory, idea_factory):
phase, module, project, idea = setup_phase(
phase_factory, idea_factory, phases.FeedbackPhase
)
url = project.get_absolute_url()
url = module.get_absolute_url()

with freeze_phase(phase):
response = client.get(url)
Expand All @@ -56,7 +56,7 @@ def test_list_view_filter_set(client, phase_factory, idea_factory):
phase, module, project, idea = setup_phase(
phase_factory, idea_factory, phases.FeedbackPhase
)
url = project.get_absolute_url()
url = module.get_absolute_url()
response = client.get(url)

assert len(response.context["view"].filter_set.base_filters)
Expand Down
2 changes: 1 addition & 1 deletion tests/kiezkasse/test_views_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_list_view(client, phase_factory, proposal_factory, area_settings_factor
phase_factory, proposal_factory, phases.RequestPhase
)
area_settings_factory(module=module)
url = project.get_absolute_url()
url = module.get_absolute_url()
with freeze_phase(phase):
response = client.get(url)
assert_template_response(response, "meinberlin_kiezkasse/proposal_list.html")
Expand Down
2 changes: 1 addition & 1 deletion tests/mapideas/views/test_mapidea_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_list_view(client, phase_factory, map_idea_factory, area_settings_factor
phase_factory, map_idea_factory, phases.FeedbackPhase
)
area_settings_factory(module=module_2)
url = project.get_absolute_url()
url = module.get_absolute_url()

with freeze_phase(phase):
response = client.get(url)
Expand Down
2 changes: 1 addition & 1 deletion tests/maptopicprio/views/test_maptopic_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_list_view(client, phase_factory, maptopic_factory, area_settings_factor
phase_factory, maptopic_factory, phases.PrioritizePhase
)
area_settings_factory(module=module_2)
url = project.get_absolute_url()
url = module.get_absolute_url()

with freeze_phase(phase):
response = client.get(url)
Expand Down
Loading

0 comments on commit 7cedc7e

Please sign in to comment.