96 lines
3.2 KiB
Python
96 lines
3.2 KiB
Python
from django.utils import timezone
|
|
from django.utils.translation import gettext, gettext_lazy as _
|
|
from django.utils.translation import ngettext
|
|
from wagtail.admin.ui.tables import Column, DateColumn
|
|
from wagtail.admin.ui.tables.pages import PageStatusColumn, PageTitleColumn
|
|
from wagtail.admin.views.pages.listing import ExplorableIndexView, IndexView
|
|
from wagtail.admin.viewsets.pages import PageListingViewSet, PageViewSet
|
|
|
|
from dnscms.admin import ListingRedirectChooseParentView
|
|
from events.models import EventPage
|
|
|
|
|
|
class EventDateColumn(Column):
|
|
def get_value(self, instance):
|
|
occurrences = list(instance.occurrences.order_by("start"))
|
|
if not occurrences:
|
|
return "—"
|
|
if len(occurrences) == 1:
|
|
local = timezone.localtime(occurrences[0].start)
|
|
return local.strftime(gettext("%Y-%m-%d at %H:%M"))
|
|
count = len(occurrences)
|
|
return ngettext("%(count)d occurrence", "%(count)d occurrences", count) % {"count": count}
|
|
|
|
|
|
class OrganizersColumn(Column):
|
|
def get_value(self, instance):
|
|
names = list(instance.organizers.values_list("name", flat=True))
|
|
if not names:
|
|
return "—"
|
|
if len(names) == 1:
|
|
return names[0]
|
|
return f"{names[0]} (+{len(names) - 1})"
|
|
|
|
|
|
class EventPagePrefetchMixin:
|
|
"""Prefetch the relations the event columns read, so the listing avoids N+1."""
|
|
|
|
def annotate_queryset(self, pages):
|
|
pages = super().annotate_queryset(pages)
|
|
return pages.prefetch_related(
|
|
"occurrences",
|
|
"organizer_links__organizer",
|
|
)
|
|
|
|
|
|
class EventPageIndexView(EventPagePrefetchMixin, IndexView):
|
|
pass
|
|
|
|
|
|
class EventPageExplorableIndexView(EventPagePrefetchMixin, ExplorableIndexView):
|
|
pass
|
|
|
|
|
|
class EventChooseParentView(ListingRedirectChooseParentView):
|
|
listing_url_name = "events:index"
|
|
|
|
|
|
class EventListingMixin:
|
|
"""Shared model + columns for the standalone listing and the page explorer."""
|
|
|
|
model = EventPage
|
|
icon = "date"
|
|
columns = [
|
|
PageTitleColumn("title", label=_("Title"), sort_key="title", classname="title"),
|
|
EventDateColumn("event_date", label=_("Date"), width="13%"),
|
|
OrganizersColumn("organizers", label=_("Organizers"), width="12%"),
|
|
DateColumn(
|
|
"latest_revision_created_at",
|
|
label=_("Updated"),
|
|
sort_key="latest_revision_created_at",
|
|
width="10%",
|
|
),
|
|
PageStatusColumn("status", label=_("Status"), sort_key="live", width="10%"),
|
|
]
|
|
|
|
|
|
class EventSidebarViewSet(EventListingMixin, PageListingViewSet):
|
|
"""Standalone 'Events' sidebar entry, reached independently of the page tree."""
|
|
|
|
index_view_class = EventPageIndexView
|
|
choose_parent_view_class = EventChooseParentView
|
|
menu_label = _("Events")
|
|
menu_order = 1
|
|
add_to_admin_menu = True
|
|
ordering = "-latest_revision_created_at"
|
|
|
|
|
|
class EventExplorerViewSet(EventListingMixin, PageViewSet):
|
|
"""Applies the same columns when navigating into EventIndex via the page explorer."""
|
|
|
|
index_view_class = EventPageExplorableIndexView
|
|
|
|
|
|
event_sidebar_viewset = EventSidebarViewSet("events")
|
|
event_explorer_viewset = EventExplorerViewSet()
|