Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions adhocracy4/dashboard/components/forms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"ModuleDashboardFormSet",
]

HIDE_COMPONENT_REGISTRY = {}


class ProjectFormComponent(DashboardComponent):
"""Abstract project related dashboard component based on forms.
Expand Down Expand Up @@ -137,6 +139,16 @@ class ModuleFormComponent(ProjectFormComponent):

"""

def is_effective(self, module):
if (
HIDE_COMPONENT_REGISTRY.get(self.identifier)
and hasattr(module, "blueprint_type")
and module.blueprint_type
in HIDE_COMPONENT_REGISTRY.get(self.identifier, set())
):
return False
return True

def get_base_url(self, project_or_module):
name = "a4dashboard:dashboard-{identifier}-edit".format(
identifier=self.identifier
Expand Down
9 changes: 9 additions & 0 deletions adhocracy4/dashboard/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from . import ProjectFormComponent
from . import components
from . import forms
from .components.forms import HIDE_COMPONENT_REGISTRY


class ProjectBasicComponent(ProjectFormComponent):
Expand Down Expand Up @@ -46,6 +47,10 @@ class ModuleBasicComponent(ModuleFormComponent):
form_class = forms.ModuleBasicForm
form_template_name = "a4dashboard/includes/module_basic_form.html"

@staticmethod
def hide_for(blueprint_type: str):
HIDE_COMPONENT_REGISTRY.setdefault("module_basic", set()).add(blueprint_type)


class ModulePhasesComponent(ModuleFormSetComponent):
identifier = "phases"
Expand All @@ -56,6 +61,10 @@ class ModulePhasesComponent(ModuleFormSetComponent):
form_class = forms.PhaseFormSet
form_template_name = "a4dashboard/includes/module_phases_form.html"

@staticmethod
def hide_for(blueprint_type: str):
HIDE_COMPONENT_REGISTRY.setdefault("phases", set()).add(blueprint_type)


class ModuleAreaSettingsComponent(ModuleFormComponent):
identifier = "area_settings"
Expand Down
1 change: 1 addition & 0 deletions adhocracy4/exports/mixins/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def get_virtual_fields(self, virtual):
and not (field.one_to_one and field.remote_field.parent_link)
and field.name not in exclude
and field.name not in virtual
and field.name != "polymorphic_ctype"
):
if self.related_fields and field.name in self.related_fields:
for attr in self.related_fields[field.name]:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 5.1.11 on 2025-10-20 15:24

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("a4modules", "0008_alter_module_blueprint_type"),
("contenttypes", "0002_remove_content_type_name"),
]

operations = [
migrations.AlterModelOptions(
name="item",
options={"base_manager_name": "objects"},
),
migrations.AddField(
model_name="item",
name="polymorphic_ctype",
field=models.ForeignKey(
editable=False,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="polymorphic_%(app_label)s.%(class)s_set+",
to="contenttypes.contenttype",
),
),
]
6 changes: 4 additions & 2 deletions adhocracy4/modules/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from django.utils.translation import pgettext_lazy
from polymorphic.managers import PolymorphicManager
from polymorphic.models import PolymorphicModel

from adhocracy4.models import base
from adhocracy4.projects import models as project_models
Expand Down Expand Up @@ -425,8 +427,8 @@ def first_phase_start_date(self):
return first_phase.start_date


class Item(base.UserGeneratedContentModel):

class Item(PolymorphicModel, base.UserGeneratedContentModel):
objects = PolymorphicManager()
module = models.ForeignKey(Module, on_delete=models.CASCADE)

@cached_property
Expand Down
17 changes: 17 additions & 0 deletions adhocracy4/polls/migrations/0007_alter_poll_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.1.11 on 2025-10-20 15:24

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("a4polls", "0006_alter_answer_unique_together_answer_content_id_and_more"),
]

operations = [
migrations.AlterModelOptions(
name="poll",
options={"base_manager_name": "objects"},
),
]
4 changes: 4 additions & 0 deletions changelog/687.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### Added

- apps/dashboard: Basic and Phase Forms can now be hidden (687)
- apps/modules: Add Django-Polymorphic to Item Class
9 changes: 9 additions & 0 deletions docs/phases_and_modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ modules may overlap or run simultaneously this is called a multi module project.

- each module belongs to a project
- each module only has phases from one app
- each module must have at least one phase
- modules are ordered by weight per default
- if a project has more than one module, the modules are either clustered if they are overlapping or ordered by module start
- a project defines a "last active" module as
Expand All @@ -145,6 +146,14 @@ modules may overlap or run simultaneously this is called a multi module project.
- blueprints define which module and phase combinations are possible
- an initiator can add multiple offline events

### Custom Modules

- Standard module components can now be hidden using:
`ModulePhasesComponent.hide_for("OE")`,
`ModuleBasicComponent.hide_for("OE")`
(used in meinberlin offline-events)


## (Upcoming) challenges

Below this line only opinions no facts:
Expand Down
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ rules==3.5
XlsxWriter==3.2.0
celery==5.4.0
requests==2.32.4
django-polymorphic==4.1.0
17 changes: 17 additions & 0 deletions tests/apps/ideas/migrations/0008_alter_idea_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.1.11 on 2025-10-20 15:24

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("a4test_ideas", "0007_alter_idea_labels"),
]

operations = [
migrations.AlterModelOptions(
name="idea",
options={"base_manager_name": "objects"},
),
]
3 changes: 2 additions & 1 deletion tests/apps/ideas/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from django_ckeditor_5.fields import CKEditor5Field
from polymorphic.query import PolymorphicQuerySet

from adhocracy4.categories.fields import CategoryField
from adhocracy4.comments.models import Comment
Expand All @@ -13,7 +14,7 @@
from tests.apps.moderatorfeedback.models import ModeratorFeedback


class IdeaQuerySet(RateableQuerySet, CommentableQuerySet):
class IdeaQuerySet(RateableQuerySet, CommentableQuerySet, PolymorphicQuerySet):
pass


Expand Down
17 changes: 17 additions & 0 deletions tests/apps/locations/migrations/0002_alter_location_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.1.11 on 2025-10-20 15:24

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("a4test_locations", "0001_initial"),
]

operations = [
migrations.AlterModelOptions(
name="location",
options={"base_manager_name": "objects"},
),
]
17 changes: 17 additions & 0 deletions tests/apps/questions/migrations/0008_alter_question_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.1.11 on 2025-10-20 15:24

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("a4test_questions", "0007_verbose_name_created_modified"),
]

operations = [
migrations.AlterModelOptions(
name="question",
options={"base_manager_name": "objects"},
),
]
3 changes: 2 additions & 1 deletion tests/apps/questions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models
from polymorphic.query import PolymorphicQuerySet

from adhocracy4.categories.fields import CategoryField
from adhocracy4.comments.models import Comment
Expand All @@ -12,7 +13,7 @@
from adhocracy4.ratings.models import Rating


class QuestionQuerySet(CommentableQuerySet, RateableQuerySet):
class QuestionQuerySet(CommentableQuerySet, RateableQuerySet, PolymorphicQuerySet):
pass


Expand Down
Loading