Skip to content
Open
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
33 changes: 32 additions & 1 deletion src/open_inwoner/cms/extensions/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from django.contrib import admin, messages
from django.contrib.admin.utils import unquote
from django.shortcuts import redirect
from django.template.response import TemplateResponse
from django.urls import path, reverse
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _

Expand All @@ -11,6 +13,7 @@
from djangocms_versioning.helpers import version_list_url
from djangocms_versioning.models import Version

from .constants import Icons
from .models import CommonExtension

# States that djangocms-versioning refuses to delete, see the `forbidden` check in
Expand Down Expand Up @@ -127,7 +130,35 @@ def grouper_link(self, obj):


class CommonExtensionAdmin(PageExtensionAdmin):
pass
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path(
"menu-icons/",
self.admin_site.admin_view(self.menu_icons_view),
name="cms_extensions_menu_icons",
),
]
return custom_urls + urls

def menu_icons_view(self, request):
context = {
**self.admin_site.each_context(request),
"title": _("Menu icons"),
"icons": Icons.choices,
}
return TemplateResponse(request, "admin/menu_icons.html", context)

def formfield_for_dbfield(self, db_field, request, **kwargs):
formfield = super().formfield_for_dbfield(db_field, request, **kwargs)
if db_field.name == "menu_icon":
formfield.help_text = format_html(
'{} <a href="{}" target="_blank">{}</a>&nbsp;',
formfield.help_text,
reverse("admin:cms_extensions_menu_icons"),
_("click here to view all available icons"),
)
return formfield


admin.site.register(CommonExtension, CommonExtensionAdmin)
67 changes: 67 additions & 0 deletions src/open_inwoner/cms/extensions/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,70 @@ class Icons(models.TextChoices):
help_outline = "help_outline", _("Help")
euro = "euro", _("Benefits")
trash = "delete", _("Afval")

# Places & housing
home = "home", _("Home")
apartment = "apartment", _("Housing")
home_work = "home_work", _("Housing (work)")
place = "place", _("Location")

# Work & government
business = "business", _("Business")
work = "work", _("Work")
account_balance = "account_balance", _("Government")
gavel = "gavel", _("Permits")
assignment = "assignment", _("Forms")

# Health & care
medical_services = "medical_services", _("Healthcare")
local_hospital = "local_hospital", _("Care")
child_care = "child_care", _("Youth")
elderly = "elderly", _("Elderly")
accessible = "accessible", _("Accessibility")

# Education
school = "school", _("Education")

# Environment & animals
park = "park", _("Environment")
recycling = "recycling", _("Recycling")
pets = "pets", _("Pets")

# Traffic
directions_car = "directions_car", _("Traffic")
local_parking = "local_parking", _("Parking")

# Safety
security = "security", _("Safety")
warning = "warning", _("Warning")

# Finance
payments = "payments", _("Payments")
credit_card = "credit_card", _("Finance")
savings = "savings", _("Savings")
receipt = "receipt", _("Invoices")

# Community & contact
groups = "groups", _("Community")
forum = "forum", _("Forum")
chat = "chat", _("Chat")
mail = "mail", _("Mail")
phone = "phone", _("Contact")
support_agent = "support_agent", _("Support")

# Content & information
campaign = "campaign", _("News")
event = "event", _("Events")
calendar_today = "calendar_today", _("Calendar")
article = "article", _("Documents")
folder = "folder", _("Files")
quiz = "quiz", _("FAQ")
info = "info", _("Information")
language = "language", _("Language")

# Interface
notifications = "notifications", _("Notifications")
search = "search", _("Search")
settings = "settings", _("Settings")
favorite = "favorite", _("Favorites")
build = "build", _("Maintenance")
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Generated by Django 4.2.27 on 2026-09-17 00:00

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("extensions", "0009_alter_commonextension_menu_icon"),
]

operations = [
migrations.AlterField(
model_name="commonextension",
name="menu_icon",
field=models.CharField(
blank=True,
choices=[
("person", "User"),
("description", "Products"),
("inbox", "Inbox"),
("inventory_2", "Cases"),
("group", "Collaborate"),
("help_outline", "Help"),
("euro", "Benefits"),
("delete", "Afval"),
("home", "Home"),
("apartment", "Housing"),
("home_work", "Housing (work)"),
("place", "Location"),
("business", "Business"),
("work", "Work"),
("account_balance", "Government"),
("gavel", "Permits"),
("assignment", "Forms"),
("medical_services", "Healthcare"),
("local_hospital", "Care"),
("child_care", "Youth"),
("elderly", "Elderly"),
("accessible", "Accessibility"),
("school", "Education"),
("park", "Environment"),
("recycling", "Recycling"),
("pets", "Pets"),
("directions_car", "Traffic"),
("local_parking", "Parking"),
("security", "Safety"),
("warning", "Warning"),
("payments", "Payments"),
("credit_card", "Finance"),
("savings", "Savings"),
("receipt", "Invoices"),
("groups", "Community"),
("forum", "Forum"),
("chat", "Chat"),
("mail", "Mail"),
("phone", "Contact"),
("support_agent", "Support"),
("campaign", "News"),
("event", "Events"),
("calendar_today", "Calendar"),
("article", "Documents"),
("folder", "Files"),
("quiz", "FAQ"),
("info", "Information"),
("language", "Language"),
("notifications", "Notifications"),
("search", "Search"),
("settings", "Settings"),
("favorite", "Favorites"),
("build", "Maintenance"),
],
help_text="Icon in het menu",
max_length=32,
verbose_name="Icon",
),
),
]
Empty file.
36 changes: 36 additions & 0 deletions src/open_inwoner/cms/extensions/tests/test_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from django.urls import reverse

from cms.utils.permissions import set_current_user
from django_webtest import WebTest
from maykin_2fa.test import disable_admin_mfa

from open_inwoner.accounts.tests.factories import UserFactory
from open_inwoner.cms.extensions.constants import Icons


@disable_admin_mfa()
class MenuIconsAdminViewTests(WebTest):
def setUp(self):
set_current_user(
None
) # otherwise will assume previous user is logged in (who is often deleted after test)
return super().setUp()

def test_get_menu_icons(self):
user = UserFactory(is_staff=True, is_superuser=True)
url = reverse("admin:cms_extensions_menu_icons")

response = self.app.get(url, user=user)

self.assertEqual(response.status_code, 200)
for value, label in Icons.choices:
self.assertContains(response, value)
self.assertContains(response, label)

def test_menu_icon_help_text_links_to_menu_icons_page(self):
user = UserFactory(is_staff=True, is_superuser=True)
url = reverse("admin:extensions_commonextension_add")

response = self.app.get(url, user=user)

self.assertContains(response, reverse("admin:cms_extensions_menu_icons"))
1 change: 1 addition & 0 deletions src/open_inwoner/scss/admin/admin_overrides.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// External
@use 'material-icons/iconfont/material-icons.css';
@use 'leaflet/dist/leaflet.css';

@use './vars'; // loads the theme-specific styles too
Expand Down
27 changes: 27 additions & 0 deletions src/open_inwoner/templates/admin/menu_icons.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends "admin/base_site.html" %}
{% load i18n icon_tags %}

{% block content %}
<style>
.menu-icons-table { border-collapse: collapse; }
.menu-icons-table th, .menu-icons-table td { text-align: left; padding: 6px 12px; }
.menu-icons-table .material-icons, .menu-icons-table .material-icons-outlined { font-size: 24px; }
</style>

<table class="menu-icons-table">
<thead>
<tr>
<th>{% trans "Icon" %}</th>
<th>{% trans "Label" %}</th>
</tr>
</thead>
<tbody>
{% for value, label in icons %}
<tr>
<td>{% icon value %}</td>
<td>{{ label }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
Loading