Skip to content

Commit 6d81239

Browse files
authored
Merge pull request #371 from maykinmedia/feature/911-disable-functionality
[#911] Added configuration options and logic to hide unused functionality
2 parents 8e7c465 + cb4802b commit 6d81239

22 files changed

+446
-53
lines changed

src/open_inwoner/accounts/tests/test_profile_views.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from open_inwoner.accounts.choices import StatusChoices
77
from open_inwoner.pdc.tests.factories import CategoryFactory
88

9+
from ...questionnaire.tests.factories import QuestionnaireStepFactory
910
from ..choices import LoginTypeChoices
1011
from .factories import ActionFactory, DocumentFactory, UserFactory
1112

@@ -30,17 +31,21 @@ def test_login_required(self):
3031

3132
def test_get_empty_profile_page(self):
3233
response = self.app.get(self.url, user=self.user)
34+
3335
self.assertEquals(response.status_code, 200)
3436
self.assertContains(response, _("U heeft geen intressegebieden aangegeven."))
3537
self.assertContains(response, _("U heeft nog geen contacten."))
3638
self.assertContains(response, "0 acties staan open.")
39+
self.assertNotContains(response, reverse("questionnaire:questionnaire_list"))
3740

3841
def test_get_filled_profile_page(self):
39-
action = ActionFactory(created_by=self.user)
42+
ActionFactory(created_by=self.user)
4043
contact = UserFactory()
4144
self.user.user_contacts.add(contact)
4245
category = CategoryFactory()
4346
self.user.selected_themes.add(category)
47+
QuestionnaireStepFactory(published=True)
48+
4449
response = self.app.get(self.url, user=self.user)
4550
self.assertEquals(response.status_code, 200)
4651
self.assertContains(response, category.name)
@@ -49,6 +54,7 @@ def test_get_filled_profile_page(self):
4954
f"{contact.first_name} ({contact.get_contact_type_display()})",
5055
)
5156
self.assertContains(response, "1 acties staan open.")
57+
self.assertContains(response, reverse("questionnaire:questionnaire_list"))
5258

5359
def test_only_open_actions(self):
5460
action = ActionFactory(created_by=self.user, status=StatusChoices.closed)

src/open_inwoner/accounts/views/actions.py

+39-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from django.contrib import messages
44
from django.contrib.auth.mixins import LoginRequiredMixin
55
from django.db.models import Q
6-
from django.http.response import HttpResponseRedirect
6+
from django.http.response import Http404, HttpResponseRedirect
77
from django.urls.base import reverse, reverse_lazy
88
from django.utils.functional import cached_property
99
from django.utils.translation import gettext as _
@@ -16,6 +16,7 @@
1616
from view_breadcrumbs import BaseBreadcrumbMixin
1717

1818
from open_inwoner.components.utils import RenderableTag
19+
from open_inwoner.configurations.models import SiteConfiguration
1920
from open_inwoner.htmx.views import HtmxTemplateTagModelFormView
2021
from open_inwoner.utils.logentry import get_change_message
2122
from open_inwoner.utils.mixins import ExportMixin
@@ -25,6 +26,14 @@
2526
from ..models import Action
2627

2728

29+
class ActionsEnabledMixin:
30+
def dispatch(self, request, *args, **kwargs):
31+
config = SiteConfiguration.get_solo()
32+
if not config.show_actions:
33+
raise Http404("actions not enabled")
34+
return super().dispatch(request, *args, **kwargs)
35+
36+
2837
class BaseActionFilter:
2938
"""
3039
For when in the template the action tag is used. This will filter the actions correctly.
@@ -44,7 +53,11 @@ def get_actions(self, actions):
4453

4554

4655
class ActionListView(
47-
LoginRequiredMixin, BaseBreadcrumbMixin, BaseActionFilter, ListView
56+
ActionsEnabledMixin,
57+
LoginRequiredMixin,
58+
BaseBreadcrumbMixin,
59+
BaseActionFilter,
60+
ListView,
4861
):
4962
template_name = "pages/profile/actions/list.html"
5063
model = Action
@@ -78,7 +91,9 @@ def get_context_data(self, **kwargs):
7891
return context
7992

8093

81-
class ActionUpdateView(LogMixin, LoginRequiredMixin, BaseBreadcrumbMixin, UpdateView):
94+
class ActionUpdateView(
95+
ActionsEnabledMixin, LogMixin, LoginRequiredMixin, BaseBreadcrumbMixin, UpdateView
96+
):
8297
template_name = "pages/profile/actions/edit.html"
8398
model = Action
8499
slug_field = "uuid"
@@ -149,7 +164,12 @@ def form_valid(self, form):
149164

150165

151166
class ActionDeleteView(
152-
LogMixin, LoginRequiredMixin, DeletionMixin, SingleObjectMixin, View
167+
ActionsEnabledMixin,
168+
LogMixin,
169+
LoginRequiredMixin,
170+
DeletionMixin,
171+
SingleObjectMixin,
172+
View,
153173
):
154174
model = Action
155175
slug_field = "uuid"
@@ -183,7 +203,9 @@ def on_delete_action(self, action):
183203
)
184204

185205

186-
class ActionCreateView(LogMixin, LoginRequiredMixin, BaseBreadcrumbMixin, CreateView):
206+
class ActionCreateView(
207+
ActionsEnabledMixin, LogMixin, LoginRequiredMixin, BaseBreadcrumbMixin, CreateView
208+
):
187209
template_name = "pages/profile/actions/edit.html"
188210
model = Action
189211
form_class = ActionForm
@@ -212,7 +234,9 @@ def form_valid(self, form):
212234
return HttpResponseRedirect(self.get_success_url())
213235

214236

215-
class ActionListExportView(LogMixin, LoginRequiredMixin, ExportMixin, ListView):
237+
class ActionListExportView(
238+
ActionsEnabledMixin, LogMixin, LoginRequiredMixin, ExportMixin, ListView
239+
):
216240
template_name = "export/profile/action_list_export.html"
217241
model = Action
218242

@@ -228,7 +252,9 @@ def get_queryset(self):
228252
)
229253

230254

231-
class ActionExportView(LogMixin, LoginRequiredMixin, ExportMixin, DetailView):
255+
class ActionExportView(
256+
ActionsEnabledMixin, LogMixin, LoginRequiredMixin, ExportMixin, DetailView
257+
):
232258
template_name = "export/profile/action_export.html"
233259
model = Action
234260
slug_field = "uuid"
@@ -241,7 +267,9 @@ def get_queryset(self):
241267
)
242268

243269

244-
class ActionPrivateMediaView(LogMixin, LoginRequiredMixin, PrivateMediaView):
270+
class ActionPrivateMediaView(
271+
ActionsEnabledMixin, LogMixin, LoginRequiredMixin, PrivateMediaView
272+
):
245273
model = Action
246274
slug_field = "uuid"
247275
slug_url_kwarg = "uuid"
@@ -262,7 +290,9 @@ def has_permission(self):
262290
return False
263291

264292

265-
class ActionHistoryView(LoginRequiredMixin, BaseBreadcrumbMixin, DetailView):
293+
class ActionHistoryView(
294+
ActionsEnabledMixin, LoginRequiredMixin, BaseBreadcrumbMixin, DetailView
295+
):
266296
template_name = "pages/history.html"
267297
model = Action
268298
slug_field = "uuid"

src/open_inwoner/accounts/views/profile.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,12 @@ def get_context_data(self, **kwargs):
7878
] = f"{', '.join(contact_names)}{'...' if contacts.count() > 3 else ''}"
7979
else:
8080
context["contact_text"] = _("U heeft nog geen contacten.")
81-
context["questionnaire_exists"] = QuestionnaireStep.objects.exists()
81+
82+
context["questionnaire_exists"] = QuestionnaireStep.objects.filter(
83+
published=True
84+
).exists()
8285
context["can_change_password"] = user.login_type != LoginTypeChoices.digid
86+
8387
return context
8488

8589
def post(self, request, *args, **kwargs):

src/open_inwoner/components/templates/components/Action/Actions.html

+5-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@
4545
<div class="actions__label">
4646
<div class="table__explain">{% trans "Onderdeel van" %}</div>
4747
{% if action.plan %}
48-
{% link href=action.plan.get_absolute_url text=action.plan.title %}
48+
{% if show_plans %}
49+
{% link href=action.plan.get_absolute_url text=action.plan.title %}
50+
{% else %}
51+
{{ action.plan.title }}
52+
{% endif %}
4953
{% else %}
5054
-
5155
{% endif %}

src/open_inwoner/components/templates/components/Header/Header.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
{% endrender_form %}
4444
</nav>
4545

46-
{% primary_navigation categories=categories request=request has_general_faq_questions=has_general_faq_questions %}
46+
{% primary_navigation categories=categories request=request has_general_faq_questions=has_general_faq_questions show_plans=config.show_plans %}
4747
</div>
4848
</div>
4949

@@ -78,6 +78,6 @@
7878
{% endrender_form %}
7979
</nav>
8080

81-
{% primary_navigation categories=categories request=request has_general_faq_questions=has_general_faq_questions %}
81+
{% primary_navigation categories=categories request=request has_general_faq_questions=has_general_faq_questions show_plans=config.show_plans %}
8282
</div>
8383
</header>

src/open_inwoner/components/templates/components/Header/PrimaryNavigation.html

+2
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@
4242
{% link text=_('Mijn aanvragen') href='accounts:my_open_cases' icon="inventory_2" icon_position="before" icon_outlined=True %}
4343
</li>
4444
{% endif %}
45+
{% if show_plans %}
4546
<li class="primary-navigation__list-item">
4647
{% link text=_('Samenwerken') href='plans:plan_list' icon="people" icon_outlined=True icon_position="before" %}
4748
</li>
49+
{% endif %}
4850
{% endif %}
4951
{% if has_general_faq_questions %}
5052
<li class="primary-navigation__list-item">

src/open_inwoner/components/templatetags/action_tags.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,14 @@ def actions(actions, request, action_form, **kwargs):
2222
+ action_form: Form | The form containing the needed filters for the actions.
2323
- form_action: string | A url for something
2424
- plan: Plan | The plan that the actions belong to.
25+
- show_plans: bool | If plan functionality is enabled
2526
"""
26-
kwargs.update(actions=actions, request=request, action_form=action_form)
27+
kwargs.update(
28+
actions=actions,
29+
request=request,
30+
action_form=action_form,
31+
show_plans=kwargs.get("show_plans", True),
32+
)
2733
return kwargs
2834

2935

src/open_inwoner/components/templatetags/header_tags.py

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def primary_navigation(categories, request, **kwargs):
5858
+ request: Request | The django request object.
5959
+ questionnaire: QuestionnaireStep | The default QuestionnaireStep, if any.
6060
- has_general_faq_questions: boolean | If the FAQ menu item should be shown.
61+
- show_plans: boolean | If the Plan item should be shown.
6162
"""
6263

6364
return {

src/open_inwoner/configurations/admin.py

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class SiteConfigurarionAdmin(OrderedInlineModelAdminMixin, SingletonModelAdmin):
4040
"login_allow_registration",
4141
"show_cases",
4242
"show_product_finder",
43+
"show_plans",
44+
"show_actions",
4345
)
4446
},
4547
),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 3.2.15 on 2022-12-06 10:21
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("configurations", "0026_alter_siteconfiguration_select_questionnaire_intro"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="siteconfiguration",
15+
name="show_plans",
16+
field=models.BooleanField(
17+
default=True,
18+
help_text="Als dit is aangevinkt, dan wordt op de homepagina en het gebruikers profiel de samenwerken feature weergegeven.",
19+
verbose_name="Laat samenwerken zien op de homepage en menu",
20+
),
21+
),
22+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 3.2.15 on 2022-12-06 12:34
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("configurations", "0027_siteconfiguration_show_plans"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="siteconfiguration",
15+
name="show_actions",
16+
field=models.BooleanField(
17+
default=True,
18+
help_text="Als dit is aangevinkt, dan worded op de gebruikers profiel pagina de acties weergegeven.",
19+
verbose_name="Laat acties zien op de profiel pagina",
20+
),
21+
),
22+
]

src/open_inwoner/configurations/models.py

+22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from django.contrib.flatpages.models import FlatPage
2+
from django.core.exceptions import ValidationError
23
from django.db import models
34
from django.urls import reverse
45
from django.utils.translation import ugettext_lazy as _
@@ -331,6 +332,20 @@ class SiteConfiguration(SingletonModel):
331332
"Als dit is aangevinkt en er zijn product condities gemaakt, dan wordt op de homepagina de productzoeker weergegeven."
332333
),
333334
)
335+
show_plans = models.BooleanField(
336+
verbose_name=_("Laat samenwerken zien op de homepage en menu"),
337+
default=True,
338+
help_text=_(
339+
"Als dit is aangevinkt, dan wordt op de homepagina en het gebruikers profiel de samenwerken feature weergegeven."
340+
),
341+
)
342+
show_actions = models.BooleanField(
343+
verbose_name=_("Laat acties zien op de profiel pagina"),
344+
default=True,
345+
help_text=_(
346+
"Als dit is aangevinkt, dan worded op de gebruikers profiel pagina de acties weergegeven."
347+
),
348+
)
334349
openid_connect_logo = FilerImageField(
335350
verbose_name=_("Openid Connect Logo"),
336351
null=True,
@@ -354,6 +369,13 @@ class Meta:
354369
def __str__(self):
355370
return str(_("Site Configuration"))
356371

372+
def clean(self):
373+
super().clean()
374+
375+
if self.show_plans and not self.show_actions:
376+
msg = _("Als Samenwerken actief is moeten Acties ook actief zijn")
377+
raise ValidationError({"show_actions": msg, "show_plans": msg})
378+
357379
@property
358380
def get_primary_color(self):
359381
return self.hex_to_hsl(self.primary_color)

0 commit comments

Comments
 (0)