Skip to content

Commit

Permalink
[Main Nav] Nav Settings [TP1-38](#12137)
Browse files Browse the repository at this point in the history
* Better panels on NavMenu

* Add SiteNavMenu setting

* Show only default locale nav menus on settings

* Fix donate banner test

* Add title and locale to NavDropdownFactory

* Remove print statements
  • Loading branch information
jhonatan-lopes authored Apr 4, 2024
1 parent e141850 commit 1d76c60
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 2 deletions.
5 changes: 3 additions & 2 deletions network-api/networkapi/donate_banner/tests.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse
from wagtail.admin.viewsets import viewsets
from wagtail.admin.viewsets import viewsets as wagtail_admin_viewsets
from wagtail.admin.viewsets.chooser import ChooserViewSet
from wagtail.models import Locale
from wagtail.test.utils import WagtailTestUtils
Expand All @@ -17,7 +17,8 @@ def is_donate_banner_chooser_viewset(self, viewset):
def get_chooser_viewset(self):
# Get the last registered ChooserViewSet for the DonateBanner model.
# Note: There can be multiple ChooserViewSets registered for a model.
model_viewsets = [x for x in viewsets.viewsets if self.is_donate_banner_chooser_viewset(x)]
wagtail_admin_viewsets.populate()
model_viewsets = [x for x in wagtail_admin_viewsets.viewsets if self.is_donate_banner_chooser_viewset(x)]
return model_viewsets[-1]

def setUp(self):
Expand Down
2 changes: 2 additions & 0 deletions network-api/networkapi/nav/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class Params:
)
no_button = factory.Trait(button=[])

title = factory.Faker("sentence", nb_words=3)
overview = wagtail_factories.ListBlockFactory(NavOverviewFactory)
columns = wagtail_factories.ListBlockFactory(
NavColumnFactory,
Expand Down Expand Up @@ -247,3 +248,4 @@ class Meta:
"3": "dropdown",
},
)
locale = factory.LazyFunction(lambda: wagtail_models.Locale.get_default())
42 changes: 42 additions & 0 deletions network-api/networkapi/nav/migrations/0002_sitenavmenu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Generated by Django 4.2.11 on 2024-04-02 12:26

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


class Migration(migrations.Migration):

dependencies = [
("wagtailcore", "0089_log_entry_data_json_null_to_object"),
("nav", "0001_initial"),
]

operations = [
migrations.CreateModel(
name="SiteNavMenu",
fields=[
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
(
"active_nav_menu",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="site_nav_menu",
verbose_name="Active Navigation Menu",
to="nav.navmenu",
),
),
(
"site",
models.OneToOneField(
editable=False, on_delete=django.db.models.deletion.CASCADE, to="wagtailcore.site"
),
),
],
options={
"verbose_name": "Navigation Menu",
"verbose_name_plural": "Navigation Menus",
},
),
]
33 changes: 33 additions & 0 deletions network-api/networkapi/nav/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from django.db import models
from wagtail import models as wagtail_models
from wagtail.admin import panels
from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
from wagtail.fields import StreamField
from wagtail.search import index
from wagtail_localize.fields import TranslatableField

from networkapi.nav import blocks as nav_blocks

Expand All @@ -26,13 +29,43 @@ class NavMenu(
)

panels = [
panels.HelpPanel(content="To enable a navigation menu on a site, go to Settings > Navigation Menus."),
panels.FieldPanel("title"),
panels.FieldPanel("dropdowns"),
]

translatable_fields = [
TranslatableField("title"),
TranslatableField("dropdowns"),
]

search_fields = [
index.SearchField("title"),
]

class Meta(wagtail_models.TranslatableMixin.Meta):
verbose_name = "Navigation Menu"
verbose_name_plural = "Navigation Menus"

def __str__(self) -> str:
return self.title


@register_setting
class SiteNavMenu(BaseSiteSetting):
active_nav_menu = models.ForeignKey(
"nav.NavMenu",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="site_nav_menu",
verbose_name="Active Navigation Menu",
)

content_panels = [
panels.FieldPanel("active_nav_menu"),
]

class Meta:
verbose_name = "Navigation Menu"
verbose_name_plural = "Navigation Menus"
58 changes: 58 additions & 0 deletions network-api/networkapi/nav/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse
from wagtail.admin.viewsets import viewsets as wagtail_admin_viewsets
from wagtail.admin.viewsets.chooser import ChooserViewSet
from wagtail.models import Locale
from wagtail.test.utils import WagtailTestUtils

from networkapi.nav import factories as nav_factories
from networkapi.nav import models as nav_models


class TestNavMenuSnippetChooser(WagtailTestUtils, TestCase):
def is_nav_menu_chooser_viewset(self, viewset):
return viewset.model == nav_models.NavMenu and issubclass(viewset.__class__, ChooserViewSet)

def get_chooser_viewset(self):
# Get the last registered ChooserViewSet for the NavMenu model.
# Note: There can be multiple ChooserViewSets registered for a model.
wagtail_admin_viewsets.populate()
model_viewsets = [x for x in wagtail_admin_viewsets.viewsets if self.is_nav_menu_chooser_viewset(x)]
return model_viewsets[-1]

def setUp(self):
# Get the chooser url from the viewsets registry.
# Would have been easier to get from model.snippet_viewset, but
# that does not work somehow.
chooser_viewset = self.get_chooser_viewset()
self.chooser_url = reverse(f"{chooser_viewset.name}:choose")

User = get_user_model()
self.user = User.objects.create_superuser("admin-user", "[email protected]", "password")
self.client.force_login(self.user)

self.default_locale = Locale.get_default()
self.fr_locale = Locale.objects.create(language_code="fr")
self.menus = [
nav_factories.NavMenuFactory.create(title="Generic"),
nav_factories.NavMenuFactory.create(title="Foundation"),
nav_factories.NavMenuFactory.create(title="Mozfest"),
]

def test_menu_chooser_exclude_locale(self):
translated_menu = self.menus[0].copy_for_translation(self.fr_locale)
translated_menu.save()
all_menus = nav_models.NavMenu.objects.all()
default_menus = nav_models.NavMenu.objects.filter(locale=self.default_locale)
response = self.client.get(self.chooser_url)
results = response.context["results"]

# Chooser does not include every menu, but only the default language ones
self.assertNotEqual(len(results), all_menus.count())
self.assertEqual(len(results), default_menus.count())
self.assertNotIn(translated_menu, results)
self.assertIn(self.menus[0], results)

# Menu chooser should not contain locale filter
self.assertNotContains(response, "id_locale")
16 changes: 16 additions & 0 deletions network-api/networkapi/nav/wagtail_hooks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
from wagtail import hooks
from wagtail.snippets.models import register_snippet
from wagtail.snippets.views.snippets import SnippetViewSet, SnippetViewSetGroup

from networkapi.nav.models import NavMenu
from networkapi.wagtailcustomization.views.snippet_chooser import (
DefaultLocaleSnippetChooserViewSet,
)


# Customise chooser to only show the default language nav menus as options.
# We do not want editors to select the translations as
# localisation will be handled on the template instead.
@hooks.register("register_admin_viewset")
def register_nav_menu_chooser_viewset():
return DefaultLocaleSnippetChooserViewSet(
"wagtailsnippetchoosers_custom_navmenu",
model=NavMenu,
url_prefix="nav/chooser",
)


class NavMenuViewSet(SnippetViewSet):
Expand Down

0 comments on commit 1d76c60

Please sign in to comment.