filter on future events when fetching for home page / event index

This commit is contained in:
2024-05-20 22:00:02 +02:00
parent 10227ff8e3
commit 856f39bb58
6 changed files with 83 additions and 43 deletions

View File

@ -1,7 +1,9 @@
from django import forms
from django.db import models
from django.db.models import Min, Q
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from grapple.helpers import register_query_field
from grapple.helpers import register_query_field, register_singular_query_field
from grapple.models import (
GraphQLBoolean,
GraphQLCollection,
@ -25,17 +27,31 @@ from wagtail.admin.panels import (
)
from wagtail.fields import StreamField
from wagtail.images.blocks import ImageChooserBlock
from wagtail.models import Orderable, Page
from wagtail.models import Orderable, Page, PageManager, PageQuerySet
from wagtail.snippets.models import register_snippet
from venues.models import VenuePage
@register_singular_query_field("eventIndex")
class EventIndex(Page):
# there can only be one event index page
max_count = 1
subpage_types = ["events.EventPage"]
def future_events(self, info, **kwargs):
return EventPage.objects.future().order_by("next_occurrence")
graphql_fields = [
GraphQLCollection(
GraphQLForeignKey,
"future_events",
"events.EventPage",
required=True,
item_required=True,
is_queryset=True,
),
]
@register_snippet
@register_query_field("eventCategory", "eventCategories")
@ -108,23 +124,22 @@ class EventOrganizer(ClusterableModel):
return self.name
class EventPageQuerySet(PageQuerySet):
def future(self):
today = timezone.localtime(timezone.now()).date()
next_occurrence = Min("occurrences__start", filter=Q(occurrences__start__gte=today))
return self.filter(occurrences__start__gte=today).annotate(next_occurrence=next_occurrence)
EventPageManager = PageManager.from_queryset(EventPageQuerySet)
class EventPage(Page):
# no children
subpage_types = []
parent_page_types = ["events.EventIndex"]
# should not be able to be shown in menus
show_in_menus = False
# inherited from Page:
# title = text
# slug = text (in promote panel)
# content_type = points to this model
# live = bool
# owner = page creator
# first_published_at = datetime
# last_published_at = datetime
# seo_title: text (in promote panel)
# search_description: text (in promote panel)
objects = EventPageManager()
featured_image = models.ForeignKey(
"images.CustomImage",
@ -167,8 +182,6 @@ class EventPage(Page):
help_text="Lenke direkte til arrangementet på Facebook",
)
# "event_organizers": [390, 322],
price_regular = models.IntegerField(null=True, blank=True)
price_student = models.IntegerField(null=True, blank=True)
price_member = models.IntegerField(null=True, blank=True)

View File

@ -1,7 +1,7 @@
import { getClient } from "@/app/client";
import { EventContainer } from "@/components/events/EventContainer";
import {
allEventsQuery,
futureEventsQuery,
EventFragment,
EventCategory,
EventOccurrence,
@ -10,8 +10,8 @@ import { PageHeader } from "@/components/general/PageHeader";
import { Suspense } from "react";
export default async function Page() {
const { data, error } = await getClient().query(allEventsQuery, {});
const events = (data?.events ?? []) as EventFragment[];
const { data, error } = await getClient().query(futureEventsQuery, {});
const events = (data?.events?.futureEvents ?? []) as EventFragment[];
const eventCategories = (data?.eventCategories ?? []) as EventCategory[];
return (

View File

@ -19,8 +19,14 @@ const HomeFragmentDefinition = graphql(`
export default async function Home() {
const homeQuery = graphql(`
query home {
events: pages(contentType: "events.EventPage") {
...Event
events: eventIndex {
... on EventIndex {
futureEvents {
... on EventPage {
...Event
}
}
}
}
home: page(contentType: "home.HomePage", urlPath: "/home/") {
... on HomePage {
@ -30,7 +36,7 @@ export default async function Home() {
}
`);
const { data, error } = await getClient().query(homeQuery, {});
const events = (data?.events ?? []) as EventFragment[];
const events = (data?.events?.futureEvents ?? []) as EventFragment[];
const home = (data?.home ?? []) as HomeFragment;
const featuredEventIds = home.featuredEvents.map((x) => x.id);

View File

@ -28,11 +28,11 @@ const documents = {
"\n fragment Venue on VenuePage {\n __typename\n id\n slug\n title\n body {\n id\n blockType\n field\n ... on RichTextBlock {\n rawValue\n value\n }\n }\n featuredImage {\n ...Image\n }\n showAsBookable\n floor\n preposition\n capabilityAudio\n capabilityAudioVideo\n capabilityBar\n capabilityLighting\n capacityLegal\n capacityStanding\n capacitySitting\n }\n": types.VenueFragmentDoc,
"\n query allVenues {\n venues: pages(contentType: \"venues.VenuePage\") {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n ": types.AllVenuesDocument,
"\n fragment Home on HomePage {\n ... on HomePage {\n featuredEvents {\n id\n }\n }\n }\n": types.HomeFragmentDoc,
"\n query home {\n events: pages(contentType: \"events.EventPage\") {\n ...Event\n }\n home: page(contentType: \"home.HomePage\", urlPath: \"/home/\") {\n ... on HomePage {\n ...Home\n }\n }\n }\n ": types.HomeDocument,
"\n query home {\n events: eventIndex {\n ... on EventIndex {\n futureEvents {\n ... on EventPage {\n ...Event\n }\n }\n }\n }\n home: page(contentType: \"home.HomePage\", urlPath: \"/home/\") {\n ... on HomePage {\n ...Home\n }\n }\n }\n ": types.HomeDocument,
"\n fragment Blocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n rawValue\n value\n }\n ... on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n ... on ImageSliderBlock {\n images {\n ... on ImageSliderItemBlock {\n image {\n ...Image\n }\n text\n }\n }\n }\n }\n": types.BlocksFragmentDoc,
"\n fragment Image on CustomImage {\n id\n url\n width\n height\n alt\n attribution\n }\n": types.ImageFragmentDoc,
"\n fragment Event on EventPage {\n __typename\n id\n slug\n title\n body {\n id\n blockType\n field\n ... on RichTextBlock {\n rawValue\n value\n }\n }\n featuredImage {\n ...Image\n }\n facebookUrl\n ticketUrl\n priceRegular\n priceMember\n priceStudent\n categories {\n ... on EventCategory {\n name\n slug\n }\n }\n occurrences {\n ... on EventOccurrence {\n __typename\n id\n start\n end\n venue {\n __typename\n id\n slug\n title\n }\n }\n }\n }\n": types.EventFragmentDoc,
"\n query allEvents {\n events: pages(contentType: \"events.EventPage\") {\n ... on EventPage {\n ...Event\n }\n }\n eventCategories: eventCategories {\n ... on EventCategory {\n name\n slug\n showInFilters\n }\n }\n }\n": types.AllEventsDocument,
"\n query futureEvents {\n events: eventIndex {\n ... on EventIndex {\n futureEvents {\n ... on EventPage {\n ...Event\n }\n }\n }\n }\n eventCategories: eventCategories {\n ... on EventCategory {\n name\n slug\n showInFilters\n }\n }\n }\n": types.FutureEventsDocument,
};
/**
@ -112,7 +112,7 @@ export function graphql(source: "\n fragment Home on HomePage {\n ... on Hom
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query home {\n events: pages(contentType: \"events.EventPage\") {\n ...Event\n }\n home: page(contentType: \"home.HomePage\", urlPath: \"/home/\") {\n ... on HomePage {\n ...Home\n }\n }\n }\n "): (typeof documents)["\n query home {\n events: pages(contentType: \"events.EventPage\") {\n ...Event\n }\n home: page(contentType: \"home.HomePage\", urlPath: \"/home/\") {\n ... on HomePage {\n ...Home\n }\n }\n }\n "];
export function graphql(source: "\n query home {\n events: eventIndex {\n ... on EventIndex {\n futureEvents {\n ... on EventPage {\n ...Event\n }\n }\n }\n }\n home: page(contentType: \"home.HomePage\", urlPath: \"/home/\") {\n ... on HomePage {\n ...Home\n }\n }\n }\n "): (typeof documents)["\n query home {\n events: eventIndex {\n ... on EventIndex {\n futureEvents {\n ... on EventPage {\n ...Event\n }\n }\n }\n }\n home: page(contentType: \"home.HomePage\", urlPath: \"/home/\") {\n ... on HomePage {\n ...Home\n }\n }\n }\n "];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@ -128,7 +128,7 @@ export function graphql(source: "\n fragment Event on EventPage {\n __typena
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query allEvents {\n events: pages(contentType: \"events.EventPage\") {\n ... on EventPage {\n ...Event\n }\n }\n eventCategories: eventCategories {\n ... on EventCategory {\n name\n slug\n showInFilters\n }\n }\n }\n"): (typeof documents)["\n query allEvents {\n events: pages(contentType: \"events.EventPage\") {\n ... on EventPage {\n ...Event\n }\n }\n eventCategories: eventCategories {\n ... on EventCategory {\n name\n slug\n showInFilters\n }\n }\n }\n"];
export function graphql(source: "\n query futureEvents {\n events: eventIndex {\n ... on EventIndex {\n futureEvents {\n ... on EventPage {\n ...Event\n }\n }\n }\n }\n eventCategories: eventCategories {\n ... on EventCategory {\n name\n slug\n showInFilters\n }\n }\n }\n"): (typeof documents)["\n query futureEvents {\n events: eventIndex {\n ... on EventIndex {\n futureEvents {\n ... on EventPage {\n ...Event\n }\n }\n }\n }\n eventCategories: eventCategories {\n ... on EventCategory {\n name\n slug\n showInFilters\n }\n }\n }\n"];
export function graphql(source: string) {
return (documents as any)[source] ?? {};

File diff suppressed because one or more lines are too long

View File

@ -68,11 +68,15 @@ const EventFragmentDefinition = graphql(`
}
`);
export const allEventsQuery = graphql(`
query allEvents {
events: pages(contentType: "events.EventPage") {
... on EventPage {
...Event
export const futureEventsQuery = graphql(`
query futureEvents {
events: eventIndex {
... on EventIndex {
futureEvents {
... on EventPage {
...Event
}
}
}
}
eventCategories: eventCategories {