diff --git a/changelog/_1111.md b/changelog/_1111.md new file mode 100644 index 0000000000..ffaed66b6c --- /dev/null +++ b/changelog/_1111.md @@ -0,0 +1,4 @@ +### Removed + +- **Breaking Change** prepare the removal of the activities (face2face) app and delete the + associated models and views diff --git a/meinberlin/apps/activities/admin.py b/meinberlin/apps/activities/admin.py deleted file mode 100644 index 7c31a246c1..0000000000 --- a/meinberlin/apps/activities/admin.py +++ /dev/null @@ -1,25 +0,0 @@ -from django import forms -from django.contrib import admin -from django_ckeditor_5.widgets import CKEditor5Widget - -from . import models - - -class ActivityAdminForm(forms.ModelForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self.fields["description"].widget = CKEditor5Widget( - config_name="collapsible-image-editor", - ) - - class Meta: - model = models.Activity - fields = "__all__" - - -class ActivityAdmin(admin.ModelAdmin): - form = ActivityAdminForm - - -admin.site.register(models.Activity, ActivityAdmin) diff --git a/meinberlin/apps/activities/dashboard.py b/meinberlin/apps/activities/dashboard.py deleted file mode 100644 index 32f84666db..0000000000 --- a/meinberlin/apps/activities/dashboard.py +++ /dev/null @@ -1,40 +0,0 @@ -from django.urls import reverse -from django.utils.translation import gettext_lazy as _ - -from adhocracy4.dashboard import DashboardComponent -from adhocracy4.dashboard import components - -from . import models -from . import views - - -class ActivityComponent(DashboardComponent): - identifier = "facetoface" - weight = 20 - label = _("Face-to-Face Information") - - def is_effective(self, module): - module_app = module.phases[0].content().app - return module_app == "meinberlin_activities" - - def get_progress(self, module): - if models.Activity.objects.filter(module=module).exists(): - return 1, 1 - return 0, 1 - - def get_base_url(self, module): - return reverse( - "a4dashboard:activities-dashboard", kwargs={"module_slug": module.slug} - ) - - def get_urls(self): - return [ - ( - r"^modules/(?P[-\w_]+)/activities/$", - views.ActivityDashboardView.as_view(component=self), - "activities-dashboard", - ) - ] - - -components.register_module(ActivityComponent()) diff --git a/meinberlin/apps/activities/forms.py b/meinberlin/apps/activities/forms.py deleted file mode 100644 index 370b74e500..0000000000 --- a/meinberlin/apps/activities/forms.py +++ /dev/null @@ -1,9 +0,0 @@ -from django import forms - -from . import models - - -class ActivityForm(forms.ModelForm): - class Meta: - model = models.Activity - fields = ["name", "highlight", "description"] diff --git a/meinberlin/apps/activities/migrations/0005_delete_activity.py b/meinberlin/apps/activities/migrations/0005_delete_activity.py new file mode 100644 index 0000000000..52f781d194 --- /dev/null +++ b/meinberlin/apps/activities/migrations/0005_delete_activity.py @@ -0,0 +1,15 @@ +# Generated by Django 4.2 on 2023-12-14 13:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("meinberlin_activities", "0004_alter_activity_description"), + ] + + operations = [ + migrations.DeleteModel( + name="Activity", + ), + ] diff --git a/meinberlin/apps/activities/models.py b/meinberlin/apps/activities/models.py deleted file mode 100644 index 614f7a0582..0000000000 --- a/meinberlin/apps/activities/models.py +++ /dev/null @@ -1,34 +0,0 @@ -from autoslug import AutoSlugField -from django.db import models -from django.utils.translation import gettext_lazy as _ -from django_ckeditor_5.fields import CKEditor5Field - -from adhocracy4 import transforms as html_transforms -from adhocracy4.modules import models as module_models - - -class Activity(module_models.Item): - slug = AutoSlugField(populate_from="name", unique=True) - name = models.CharField(max_length=120, verbose_name=_("Title")) - highlight = models.CharField( - max_length=120, - verbose_name=_("Highlighted Info"), - help_text=_( - "Highlight important information like the time " - "or location of your face-to-face event" - ), - ) - description = CKEditor5Field( - config_name="collapsible-image-editor", verbose_name=_("Description") - ) - - def get_absolute_url(self): - return self.project.get_absolute_url() - - def save(self, update_fields=None, *args, **kwargs): - self.description = html_transforms.clean_html_field( - self.description, "collapsible-image-editor" - ) - if update_fields: - update_fields = {"description"}.union(update_fields) - super().save(update_fields=update_fields, *args, **kwargs) diff --git a/meinberlin/apps/activities/phases.py b/meinberlin/apps/activities/phases.py deleted file mode 100644 index 27c098c9aa..0000000000 --- a/meinberlin/apps/activities/phases.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.utils.translation import gettext_lazy as _ - -from adhocracy4 import phases - -from . import apps -from . import views - - -class FaceToFacePhase(phases.PhaseContent): - app = apps.Config.label - phase = "facetoface" - view = views.ActivityView - - name = _("Face to face phase") - description = _("Provide information about face-to-face participation " "events.") - module_name = _("facetoface") - - features = {} - - -phases.content.register(FaceToFacePhase()) diff --git a/meinberlin/apps/activities/rules.py b/meinberlin/apps/activities/rules.py deleted file mode 100644 index 509b6c5cea..0000000000 --- a/meinberlin/apps/activities/rules.py +++ /dev/null @@ -1,12 +0,0 @@ -import rules - -from adhocracy4.modules import predicates as module_predicates - -rules.add_perm( - "meinberlin_activities.change_activity", - module_predicates.is_allowed_moderate_project, -) - -rules.add_perm( - "meinberlin_activities.view_activity", module_predicates.is_allowed_view_item -) diff --git a/meinberlin/apps/activities/templates/meinberlin_activities/activities_dashboard.html b/meinberlin/apps/activities/templates/meinberlin_activities/activities_dashboard.html deleted file mode 100644 index 43848f840e..0000000000 --- a/meinberlin/apps/activities/templates/meinberlin_activities/activities_dashboard.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "a4dashboard/base_form_module.html" %} -{% load i18n %} - -{% block dashboard_project_content %} -

{% translate 'Edit face to face participation information' %}

- -
- {% csrf_token %} - - {% include 'meinberlin_contrib/includes/form_field.html' with field=form.name %} - - {% include 'meinberlin_contrib/includes/form_field.html' with field=form.highlight %} - - {% include 'meinberlin_contrib/includes/form_field.html' with field=form.description %} - -
- -
-
-{% endblock %} diff --git a/meinberlin/apps/activities/templates/meinberlin_activities/activity_detail.html b/meinberlin/apps/activities/templates/meinberlin_activities/activity_detail.html deleted file mode 100644 index cce381590d..0000000000 --- a/meinberlin/apps/activities/templates/meinberlin_activities/activity_detail.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends 'meinberlin_projects/project_detail.html' %} -{% load wagtailcore_tags ckeditor_tags %} - -{% block phase_content %} - {% include 'meinberlin_activities/includes/activity_detail_content.html' %} -{% endblock %} diff --git a/meinberlin/apps/activities/templates/meinberlin_activities/includes/activity_detail_content.html b/meinberlin/apps/activities/templates/meinberlin_activities/includes/activity_detail_content.html deleted file mode 100644 index a805f1ca6f..0000000000 --- a/meinberlin/apps/activities/templates/meinberlin_activities/includes/activity_detail_content.html +++ /dev/null @@ -1,11 +0,0 @@ -{% load wagtailcore_tags ckeditor_tags %} - -
-
-
-

{{ object.name }}

-

{{ object.highlight }}

-

{{ object.description | transform_collapsibles | richtext }}

-
-
-
diff --git a/meinberlin/apps/activities/views.py b/meinberlin/apps/activities/views.py deleted file mode 100644 index b59f6fd173..0000000000 --- a/meinberlin/apps/activities/views.py +++ /dev/null @@ -1,44 +0,0 @@ -from django.views import generic - -from adhocracy4.dashboard import mixins as dashboard_mixins -from adhocracy4.projects.mixins import ProjectMixin -from adhocracy4.rules import mixins as rules_mixins - -from . import forms -from . import models - - -class ActivityDashboardView( - ProjectMixin, - dashboard_mixins.DashboardBaseMixin, - dashboard_mixins.DashboardComponentMixin, - generic.UpdateView, -): - model = models.Activity - form_class = forms.ActivityForm - template_name = "meinberlin_activities/activities_dashboard.html" - permission_required = "meinberlin_activities.change_activity" - - def get_permission_object(self): - return self.module - - def form_valid(self, form): - form.instance.creator = self.request.user - form.instance.module = self.module - return super().form_valid(form) - - def get_object(self, queryset=None): - return models.Activity.objects.filter(module=self.module).first() - - -class ActivityView( - ProjectMixin, rules_mixins.PermissionRequiredMixin, generic.DetailView -): - model = models.Activity - permission_required = "meinberlin_activities.view_activity" - - def get_object(self): - return models.Activity.objects.filter(module=self.module).first() - - def get_permission_object(self): - return self.module diff --git a/meinberlin/apps/offlineevents/templatetags/offlineevent_tags.py b/meinberlin/apps/offlineevents/templatetags/offlineevent_tags.py index cd958f0e0f..c3af8b52c8 100644 --- a/meinberlin/apps/offlineevents/templatetags/offlineevent_tags.py +++ b/meinberlin/apps/offlineevents/templatetags/offlineevent_tags.py @@ -4,7 +4,6 @@ from adhocracy4.modules.models import Module from adhocracy4.phases.models import Phase -from meinberlin.apps.activities.models import Activity from meinberlin.apps.offlineevents.models import OfflineEvent register = template.Library() @@ -48,16 +47,3 @@ def is_module(obj): @register.filter def is_offlineevent(obj): return isinstance(obj, OfflineEvent) - - -@register.filter -def has_activity(obj): - try: - return isinstance(obj.item_set.first().activity, Activity) - except AttributeError: - try: - return isinstance( - obj.future_phases.first().module.item_set.first().activity, Activity - ) - except AttributeError: - return isinstance(obj, Activity) diff --git a/meinberlin/test/factories/activities.py b/meinberlin/test/factories/activities.py deleted file mode 100644 index 16a9a66613..0000000000 --- a/meinberlin/test/factories/activities.py +++ /dev/null @@ -1,12 +0,0 @@ -import factory - -from adhocracy4.test import factories as a4_factories -from meinberlin.apps.activities.models import Activity - - -class ActivityFactory(factory.django.DjangoModelFactory): - class Meta: - model = Activity - - creator = factory.SubFactory(a4_factories.USER_FACTORY) - module = factory.SubFactory(a4_factories.ModuleFactory) diff --git a/tests/activities/test_activity_component.py b/tests/activities/test_activity_component.py deleted file mode 100644 index ab8851a20f..0000000000 --- a/tests/activities/test_activity_component.py +++ /dev/null @@ -1,31 +0,0 @@ -import pytest - -from meinberlin.apps.activities.dashboard import ActivityComponent - - -@pytest.mark.django_db -def test_progress(module, activity_factory): - ac = ActivityComponent() - assert ac.get_progress(module) == (0, 1) - activity_factory(module=module) - assert ac.get_progress(module) == (1, 1) - - -@pytest.mark.django_db -def test_get_base_url(module, client): - ac = ActivityComponent() - url = ac.get_base_url(module) - resp = client.get(url, follow=True) - assert resp.status_code != 404 # url exists - - -@pytest.mark.django_db -def test_call_get_urls(module, client): - ac = ActivityComponent() - ac.get_urls() - - -@pytest.mark.django_db -def test_call_is_effective(module, client): - ac = ActivityComponent() - ac.get_urls() diff --git a/tests/activities/test_activity_model.py b/tests/activities/test_activity_model.py deleted file mode 100644 index d1e022fb3e..0000000000 --- a/tests/activities/test_activity_model.py +++ /dev/null @@ -1,13 +0,0 @@ -import pytest - - -@pytest.mark.django_db -def test_activity_url_is_project_url(activity_factory): - a = activity_factory() - assert a.get_absolute_url() == a.project.get_absolute_url() - - -@pytest.mark.django_db -def test_activity_description_removes_script_tag(activity_factory): - a = activity_factory(description='') - assert a.description == 'alert("I love you")' diff --git a/tests/activities/test_activity_view.py b/tests/activities/test_activity_view.py deleted file mode 100644 index bfb71fd5a7..0000000000 --- a/tests/activities/test_activity_view.py +++ /dev/null @@ -1,48 +0,0 @@ -import pytest -from django.urls import reverse - -from adhocracy4.test.helpers import setup_users - - -@pytest.mark.django_db -def test_facetoface_in_blueprints(client, project): - anonymous, moderator, initiator = setup_users(project) - client.login(username=initiator.email, password="password") - blueprints_url = reverse( - "a4dashboard:blueprint-list", - kwargs={"organisation_slug": project.organisation.slug}, - ) - # facetoface_blueprint_url = reverse( - # 'a4dashboard:project-create', - # kwargs={ - # 'blueprint_slug': 'facetoface', - # 'organisation_slug': project.organisation.slug - # }) - resp = client.get(blueprints_url, follow=True) - assert resp.status_code == 200 - # assert facetoface_blueprint_url in resp.content.decode() - - -@pytest.mark.django_db -def test_create_activity_in_dashboard(user, client, activity_factory, phase_factory): - activity = activity_factory() - phase_factory(module=activity.module) - anonymous, moderator, initiator = setup_users(activity.project) - client.login(username=initiator.email, password="password") - url = reverse( - "a4dashboard:activities-dashboard", kwargs={"module_slug": activity.module.slug} - ) - # get the page - resp = client.get(url) - assert resp.status_code == 200 - - # post invalid data - resp = client.post(url) - assert not resp.context["form"].is_valid() - - # post valid data - resp = client.post( - url, - {"name": "myname", "highlight": "myhilight", "description": "mydescription"}, - ) - assert resp.status_code == 302 # use this an an indicator for success diff --git a/tests/conftest.py b/tests/conftest.py index 6b863b7092..d0eae768d3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,7 +10,6 @@ from adhocracy4.test.factories import labels as a4_label_factories from adhocracy4.test.factories.maps import AreaSettingsFactory from meinberlin.test import factories -from meinberlin.test.factories.activities import ActivityFactory from meinberlin.test.factories.bplan import BplanFactory from meinberlin.test.factories.extprojects import ExternalProjectFactory from meinberlin.test.factories.likes import LikeFactory @@ -35,7 +34,6 @@ def pytest_configure(config): register(factories.LiveStreamFactory) register(a4_label_factories.LabelFactory) register(a4_label_factories.LabelAliasFactory) -register(ActivityFactory) register(PlanFactory) register(ExternalProjectFactory) register(BplanFactory)