add support for previewing pages

This commit is contained in:
2026-05-19 17:48:33 +02:00
parent f91c67f526
commit a5ebb897f1
25 changed files with 471 additions and 67 deletions
+3 -2
View File
@@ -10,13 +10,14 @@ from wagtail.admin.panels import FieldPanel
from wagtail.fields import RichTextField from wagtail.fields import RichTextField
from wagtail.models import Page from wagtail.models import Page
from wagtail.search import index from wagtail.search import index
from wagtail_headless_preview.models import HeadlessMixin
from dnscms.fields import CommonStreamField from dnscms.fields import CommonStreamField
from dnscms.wordpress.models import WPImportedPageMixin from dnscms.wordpress.models import WPImportedPageMixin
@register_singular_query_field("associationIndex") @register_singular_query_field("associationIndex")
class AssociationIndex(Page): class AssociationIndex(HeadlessMixin, Page):
max_count = 1 max_count = 1
subpage_types = ["associations.AssociationPage"] subpage_types = ["associations.AssociationPage"]
@@ -37,7 +38,7 @@ class AssociationIndex(Page):
search_fields = Page.search_fields search_fields = Page.search_fields
class AssociationPage(WPImportedPageMixin, Page): class AssociationPage(HeadlessMixin, WPImportedPageMixin, Page):
subpage_types = [] subpage_types = []
parent_page_types = ["associations.AssociationIndex"] parent_page_types = ["associations.AssociationIndex"]
show_in_menus = False show_in_menus = False
+2 -1
View File
@@ -11,6 +11,7 @@ from wagtail.fields import RichTextField, StreamField
from wagtail.models import Page from wagtail.models import Page
from wagtail.search import index from wagtail.search import index
from wagtail.snippets.models import register_snippet from wagtail.snippets.models import register_snippet
from wagtail_headless_preview.models import HeadlessMixin
from contacts.blocks import ContactSectionBlock from contacts.blocks import ContactSectionBlock
from dnscms.blocks import BASE_BLOCKS from dnscms.blocks import BASE_BLOCKS
@@ -22,7 +23,7 @@ PHONE_REGEX_VALIDATOR = RegexValidator(
@register_singular_query_field("contactIndex") @register_singular_query_field("contactIndex")
class ContactIndex(Page): class ContactIndex(HeadlessMixin, Page):
max_count = 1 max_count = 1
subpage_types = [] subpage_types = []
+16 -4
View File
@@ -41,6 +41,7 @@ INSTALLED_APPS = [
# end cms apps # end cms apps
"grapple", "grapple",
"graphene_django", "graphene_django",
"wagtail_headless_preview",
"wagtail.contrib.forms", "wagtail.contrib.forms",
"wagtail.contrib.redirects", "wagtail.contrib.redirects",
"wagtail.contrib.settings", "wagtail.contrib.settings",
@@ -185,11 +186,22 @@ WAGTAILSEARCH_BACKENDS = {
} }
# Base URL to use when referring to full URLs within the Wagtail admin backend - # Base URL to use when referring to full URLs within the Wagtail admin backend -
# e.g. in notification emails. Don't include '/admin' or a trailing slash # e.g. in notification emails. Don't include '/admin' or a trailing slash.
WAGTAILADMIN_BASE_URL = "http://example.com" # Also used by wagtail-grapple to make image URLs absolute.
WAGTAIL_BASE_URL = os.environ.get("WAGTAIL_BASE_URL", "http://127.0.0.1:8000").rstrip("/")
WAGTAILADMIN_BASE_URL = WAGTAIL_BASE_URL
BASE_URL = WAGTAIL_BASE_URL
# Required by wagtail-grapple to make image URLs absolute # Public URL of the Next.js frontend. Used to direct preview iframes and to
BASE_URL = "http://example.com" # redirect "View Live" clicks on the CMS host over to the headless frontend.
FRONTEND_BASE_URL = os.environ.get("FRONTEND_BASE_URL", "http://localhost:3000").rstrip("/")
WAGTAIL_HEADLESS_PREVIEW = {
"CLIENT_URLS": {"default": f"{FRONTEND_BASE_URL}/api/preview"},
"SERVE_BASE_URL": FRONTEND_BASE_URL,
"ENFORCE_TRAILING_SLASH": False,
"REDIRECT_ON_PREVIEW": False,
}
# https://docs.wagtail.org/en/latest/releases/6.4.html#data-upload-max-number-fields-update # https://docs.wagtail.org/en/latest/releases/6.4.html#data-upload-max-number-fields-update
DATA_UPLOAD_MAX_NUMBER_FIELDS = 10_000 DATA_UPLOAD_MAX_NUMBER_FIELDS = 10_000
-7
View File
@@ -11,13 +11,6 @@ ALLOWED_HOSTS = ["*"]
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
# Base URL to use when referring to full URLs within the Wagtail admin backend -
# e.g. in notification emails. Don't include '/admin' or a trailing slash
WAGTAILADMIN_BASE_URL = "http://127.0.0.1:8000"
# Required by wagtail-grapple to make image URLs absolute
BASE_URL = "http://127.0.0.1:8000"
try: try:
from .local import * from .local import *
except ImportError: except ImportError:
+4 -3
View File
@@ -30,6 +30,7 @@ from wagtail.fields import RichTextField
from wagtail.models import Orderable, Page, PageManager, PageQuerySet from wagtail.models import Orderable, Page, PageManager, PageQuerySet
from wagtail.search import index from wagtail.search import index
from wagtail.snippets.models import register_snippet from wagtail.snippets.models import register_snippet
from wagtail_headless_preview.models import HeadlessMixin
from associations.widgets import AssociationChooserWidget from associations.widgets import AssociationChooserWidget
from dnscms.fields import CommonStreamField from dnscms.fields import CommonStreamField
@@ -39,7 +40,7 @@ from venues.models import VenuePage
@register_singular_query_field("eventIndex") @register_singular_query_field("eventIndex")
class EventIndex(Page): class EventIndex(HeadlessMixin, Page):
max_count = 1 max_count = 1
subpage_types = ["events.EventPage"] subpage_types = ["events.EventPage"]
@@ -220,7 +221,7 @@ class EventPageQuerySet(PageQuerySet):
EventPageManager = PageManager.from_queryset(EventPageQuerySet) EventPageManager = PageManager.from_queryset(EventPageQuerySet)
class EventPage(WPImportedPageMixin, Page): class EventPage(HeadlessMixin, WPImportedPageMixin, Page):
subpage_types = [] subpage_types = []
parent_page_types = ["events.EventIndex"] parent_page_types = ["events.EventIndex"]
show_in_menus = False show_in_menus = False
@@ -358,7 +359,7 @@ class EventPage(WPImportedPageMixin, Page):
GraphQLImage("featured_image"), GraphQLImage("featured_image"),
GraphQLRichText("lead"), GraphQLRichText("lead"),
GraphQLStreamfield("body"), GraphQLStreamfield("body"),
GraphQLString("pig"), GraphQLString("pig", required=True),
GraphQLString("ticket_url"), GraphQLString("ticket_url"),
GraphQLString("facebook_url"), GraphQLString("facebook_url"),
GraphQLBoolean("free"), GraphQLBoolean("free"),
+2 -1
View File
@@ -4,13 +4,14 @@ from wagtail.admin.panels import FieldPanel
from wagtail.fields import RichTextField, StreamField from wagtail.fields import RichTextField, StreamField
from wagtail.models import Page from wagtail.models import Page
from wagtail.search import index from wagtail.search import index
from wagtail_headless_preview.models import HeadlessMixin
from dnscms.blocks import PageSectionBlock from dnscms.blocks import PageSectionBlock
from dnscms.fields import BASE_BLOCKS from dnscms.fields import BASE_BLOCKS
from dnscms.options import ALL_PIGS from dnscms.options import ALL_PIGS
class GenericPage(Page): class GenericPage(HeadlessMixin, Page):
subpage_types = ["generic.GenericPage"] subpage_types = ["generic.GenericPage"]
show_in_menus = True show_in_menus = True
+2 -1
View File
@@ -10,9 +10,10 @@ from wagtail.admin.panels import (
PageChooserPanel, PageChooserPanel,
) )
from wagtail.models import Orderable, Page from wagtail.models import Orderable, Page
from wagtail_headless_preview.models import HeadlessMixin
class HomePage(Page): class HomePage(HeadlessMixin, Page):
max_count = 1 max_count = 1
content_panels = Page.content_panels + [ content_panels = Page.content_panels + [
+3 -2
View File
@@ -5,13 +5,14 @@ from wagtail.admin.panels import FieldPanel
from wagtail.fields import RichTextField from wagtail.fields import RichTextField
from wagtail.models import Page from wagtail.models import Page
from wagtail.search import index from wagtail.search import index
from wagtail_headless_preview.models import HeadlessMixin
from dnscms.fields import CommonStreamField from dnscms.fields import CommonStreamField
from dnscms.wordpress.models import WPImportedPageMixin from dnscms.wordpress.models import WPImportedPageMixin
@register_singular_query_field("newsIndex") @register_singular_query_field("newsIndex")
class NewsIndex(Page): class NewsIndex(HeadlessMixin, Page):
max_count = 1 max_count = 1
subpage_types = ["news.NewsPage"] subpage_types = ["news.NewsPage"]
@@ -28,7 +29,7 @@ class NewsIndex(Page):
search_fields = [] search_fields = []
class NewsPage(WPImportedPageMixin, Page): class NewsPage(HeadlessMixin, WPImportedPageMixin, Page):
subpage_types = [] subpage_types = []
parent_page_types = ["news.NewsIndex"] parent_page_types = ["news.NewsIndex"]
show_in_menus = False show_in_menus = False
+1
View File
@@ -7,6 +7,7 @@ requires-python = ">=3.14, <3.15"
dependencies = [ dependencies = [
"wagtail>=7.4,<8", "wagtail>=7.4,<8",
"wagtail-grapple>=0.31.0,<0.32", "wagtail-grapple>=0.31.0,<0.32",
"wagtail-headless-preview>=0.8,<0.9",
"django>=6.0.5,<7", "django>=6.0.5,<7",
"django-extensions>=4.1,<5", "django-extensions>=4.1,<5",
"psycopg2-binary>=2.9.12,<3", "psycopg2-binary>=2.9.12,<3",
+2 -1
View File
@@ -8,6 +8,7 @@ from wagtail.fields import RichTextField, StreamField
from wagtail.images.blocks import ImageChooserBlock from wagtail.images.blocks import ImageChooserBlock
from wagtail.models import Page from wagtail.models import Page
from wagtail.search import index from wagtail.search import index
from wagtail_headless_preview.models import HeadlessMixin
from dnscms.blocks import BASE_BLOCKS from dnscms.blocks import BASE_BLOCKS
@@ -34,7 +35,7 @@ class SponsorBlock(blocks.StructBlock):
@register_singular_query_field("sponsorsPage") @register_singular_query_field("sponsorsPage")
class SponsorsPage(Page): class SponsorsPage(HeadlessMixin, Page):
max_count = 1 max_count = 1
subpage_types = [] subpage_types = []
+2 -1
View File
@@ -10,13 +10,14 @@ from wagtail.admin.panels import FieldPanel
from wagtail.fields import RichTextField, StreamField from wagtail.fields import RichTextField, StreamField
from wagtail.models import Page from wagtail.models import Page
from wagtail.search import index from wagtail.search import index
from wagtail_headless_preview.models import HeadlessMixin
from dnscms.blocks import BASE_BLOCKS, PageSectionBlock from dnscms.blocks import BASE_BLOCKS, PageSectionBlock
from dnscms.options import ALL_PIGS from dnscms.options import ALL_PIGS
@register_singular_query_field("studioPage") @register_singular_query_field("studioPage")
class StudioPage(Page): class StudioPage(HeadlessMixin, Page):
max_count = 1 max_count = 1
subpage_types = [] subpage_types = []
show_in_menus = True show_in_menus = True
+37
View File
@@ -0,0 +1,37 @@
"""Round-trip tests for wagtail-headless-preview token resolution via grapple."""
from generic.models import GenericPage
from tests.conftest import GenericPageFactory
def test_generic_page_preview_token_resolves_draft(home_page, graphql_post):
"""A minted preview token returns the unsaved draft via grapple's page(token: …)."""
# Publish a baseline so there's a live revision to diverge from.
page = GenericPageFactory(parent=home_page, title="Original title", slug="generic-preview")
# Mutate in-memory to simulate unsaved editor state, then mint a token.
# create_page_preview() snapshots the current to_json() into a PagePreview row.
page.title = "Edited title (draft)"
preview = page.create_page_preview()
response, body = graphql_post(
"""
query previewPage($token: String!) {
page: page(token: $token) {
__typename
... on GenericPage {
title
}
}
}
""",
variables={"token": preview.token},
)
assert response.status_code == 200
assert "errors" not in body, body
assert body["data"]["page"]["__typename"] == "GenericPage"
assert body["data"]["page"]["title"] == "Edited title (draft)"
# Live revision is unchanged — token short-circuits the published query.
assert GenericPage.objects.get(pk=page.pk).title == "Original title"
+2
View File
@@ -255,6 +255,7 @@ dependencies = [
{ name = "psycopg2-binary" }, { name = "psycopg2-binary" },
{ name = "wagtail" }, { name = "wagtail" },
{ name = "wagtail-grapple" }, { name = "wagtail-grapple" },
{ name = "wagtail-headless-preview" },
{ name = "whitenoise" }, { name = "whitenoise" },
] ]
@@ -275,6 +276,7 @@ requires-dist = [
{ name = "psycopg2-binary", specifier = ">=2.9.12,<3" }, { name = "psycopg2-binary", specifier = ">=2.9.12,<3" },
{ name = "wagtail", specifier = ">=7.4,<8" }, { name = "wagtail", specifier = ">=7.4,<8" },
{ name = "wagtail-grapple", specifier = ">=0.31.0,<0.32" }, { name = "wagtail-grapple", specifier = ">=0.31.0,<0.32" },
{ name = "wagtail-headless-preview", specifier = ">=0.8,<0.9" },
{ name = "whitenoise", specifier = ">=6.12.0,<7" }, { name = "whitenoise", specifier = ">=6.12.0,<7" },
] ]
+4 -3
View File
@@ -11,6 +11,7 @@ from wagtail.admin.panels import FieldPanel, FieldRowPanel, MultiFieldPanel
from wagtail.fields import RichTextField, StreamField from wagtail.fields import RichTextField, StreamField
from wagtail.models import Page from wagtail.models import Page
from wagtail.search import index from wagtail.search import index
from wagtail_headless_preview.models import HeadlessMixin
from dnscms.blocks import ImageSliderBlock from dnscms.blocks import ImageSliderBlock
from dnscms.fields import CommonStreamField from dnscms.fields import CommonStreamField
@@ -18,7 +19,7 @@ from dnscms.wordpress.models import WPImportedPageMixin
@register_singular_query_field("venueIndex") @register_singular_query_field("venueIndex")
class VenueIndex(Page): class VenueIndex(HeadlessMixin, Page):
# there can only be one venue index page # there can only be one venue index page
max_count = 1 max_count = 1
subpage_types = ["venues.VenuePage"] subpage_types = ["venues.VenuePage"]
@@ -35,7 +36,7 @@ class VenueIndex(Page):
@register_singular_query_field("venueRentalIndex") @register_singular_query_field("venueRentalIndex")
class VenueRentalIndex(Page): class VenueRentalIndex(HeadlessMixin, Page):
# there can only be one venue index page # there can only be one venue index page
max_count = 1 max_count = 1
subpage_types = [] subpage_types = []
@@ -51,7 +52,7 @@ class VenueRentalIndex(Page):
graphql_fields = [GraphQLRichText("lead"), GraphQLStreamfield("body")] graphql_fields = [GraphQLRichText("lead"), GraphQLStreamfield("body")]
class VenuePage(WPImportedPageMixin, Page): class VenuePage(HeadlessMixin, WPImportedPageMixin, Page):
# no children # no children
subpage_types = [] subpage_types = []
parent_page_types = ["venues.VenueIndex"] parent_page_types = ["venues.VenueIndex"]
+1 -1
View File
@@ -1,2 +1,2 @@
GRAPHQL_ENDPOINT=https://cms.neuf.no/api/graphql/ WAGTAIL_BASE_URL=https://cms.neuf.no
URL=http://localhost:3000 URL=http://localhost:3000
+7 -1
View File
@@ -3,8 +3,14 @@ import { CodegenConfig } from "@graphql-codegen/cli";
import { loadEnvConfig } from "@next/env"; import { loadEnvConfig } from "@next/env";
loadEnvConfig(process.cwd()); loadEnvConfig(process.cwd());
const wagtailBaseUrl = process.env.WAGTAIL_BASE_URL;
if (!wagtailBaseUrl) {
throw new Error("WAGTAIL_BASE_URL is not set");
}
const graphqlEndpoint = `${wagtailBaseUrl.replace(/\/$/, "")}/api/graphql/`;
const config: CodegenConfig = { const config: CodegenConfig = {
schema: process.env.GRAPHQL_ENDPOINT, schema: graphqlEndpoint,
documents: ["src/**/*.tsx", "src/**/*.ts"], documents: ["src/**/*.tsx", "src/**/*.ts"],
ignoreNoDocuments: true, // for better experience with the watcher ignoreNoDocuments: true, // for better experience with the watcher
generates: { generates: {
+7
View File
@@ -0,0 +1,7 @@
import { cookies, draftMode } from "next/headers";
export async function POST() {
(await draftMode()).disable();
(await cookies()).delete("preview-token");
return new Response(null, { status: 204 });
}
+25
View File
@@ -0,0 +1,25 @@
import { cookies, draftMode } from "next/headers";
import { redirect } from "next/navigation";
import { NextRequest } from "next/server";
// Wagtail-headless-preview directs the editor's preview iframe here with
// ?content_type=app.Model&token=<signed>. We stash the token in a cookie,
// enable Next.js draft mode, and redirect to the type-dispatching renderer.
export async function GET(req: NextRequest) {
const token = req.nextUrl.searchParams.get("token");
const contentType = req.nextUrl.searchParams.get("content_type");
if (!token || !contentType) {
return new Response("missing token/content_type", { status: 400 });
}
(await draftMode()).enable();
(await cookies()).set("preview-token", token, {
httpOnly: true,
sameSite: "lax",
secure: process.env.NODE_ENV === "production",
maxAge: 60 * 60 * 24,
path: "/",
});
redirect("/preview/render");
}
+7 -1
View File
@@ -3,9 +3,15 @@ import "server-only";
import { cacheExchange, createClient, fetchExchange } from "@urql/core"; import { cacheExchange, createClient, fetchExchange } from "@urql/core";
import { registerUrql } from "@urql/next/rsc"; import { registerUrql } from "@urql/next/rsc";
const wagtailBaseUrl = process.env.WAGTAIL_BASE_URL;
if (!wagtailBaseUrl) {
throw new Error("WAGTAIL_BASE_URL is not set");
}
const graphqlEndpoint = `${wagtailBaseUrl.replace(/\/$/, "")}/api/graphql/`;
const makeClient = () => { const makeClient = () => {
return createClient({ return createClient({
url: process.env.GRAPHQL_ENDPOINT ?? "", url: graphqlEndpoint,
exchanges: [cacheExchange, fetchExchange], exchanges: [cacheExchange, fetchExchange],
// requestPolicy: "network-only", // requestPolicy: "network-only",
fetchOptions: { next: { revalidate: 0 } }, fetchOptions: { next: { revalidate: 0 } },
+5 -1
View File
@@ -1,7 +1,9 @@
import "@/css/main.scss"; import "@/css/main.scss";
import { Header } from "@/components/layout/Header"; import { Header } from "@/components/layout/Header";
import { Footer } from "@/components/layout/Footer"; import { Footer } from "@/components/layout/Footer";
import { PreviewBanner } from "@/components/general/PreviewBanner";
import { Metadata } from "next"; import { Metadata } from "next";
import { draftMode } from "next/headers";
import { NuqsAdapter } from "nuqs/adapters/next/app"; import { NuqsAdapter } from "nuqs/adapters/next/app";
const baseUrlMetadata = process.env.URL const baseUrlMetadata = process.env.URL
@@ -26,11 +28,12 @@ export const metadata: Metadata = {
...baseUrlMetadata, ...baseUrlMetadata,
}; };
export default function RootLayout({ export default async function RootLayout({
children, children,
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
const isPreview = (await draftMode()).isEnabled;
return ( return (
<html lang="no"> <html lang="no">
<head> <head>
@@ -44,6 +47,7 @@ export default function RootLayout({
)} )}
</head> </head>
<body> <body>
{isPreview && <PreviewBanner />}
<NuqsAdapter> <NuqsAdapter>
<Header /> <Header />
{children} {children}
+191
View File
@@ -0,0 +1,191 @@
import { cookies } from "next/headers";
import { getClient } from "@/app/client";
import { graphql } from "@/gql";
import {
AssociationFragment,
AssociationIndexFragment,
ContactIndexFragment,
EventFragment,
GenericFragment,
HomeFragment,
NewsFragment,
NewsIndexFragment,
SponsorsPageFragment,
StudioFragment,
VenueFragment,
VenueIndexFragment,
VenueRentalIndexFragment,
} from "@/gql/graphql";
import {
AssociationIndexView,
allAssociationsQuery,
} from "@/components/associations/AssociationIndexView";
import { AssociationPageView } from "@/components/associations/AssociationPageView";
import { ContactIndexView } from "@/components/contact/ContactIndexView";
import { EventIndexView } from "@/components/events/EventIndexView";
import { EventPageView } from "@/components/events/EventPageView";
import { GenericPageView } from "@/components/general/GenericPageView";
import { HomePageView, homeQuery } from "@/components/home/HomePageView";
import { NewsIndexView } from "@/components/news/NewsIndexView";
import { NewsPageView } from "@/components/news/NewsPageView";
import { SponsorsPageView } from "@/components/sponsor/SponsorsPageView";
import { StudioPageView } from "@/components/studio/StudioPageView";
import {
VenueIndexView,
venueIndexQuery,
} from "@/components/venues/VenueIndexView";
import { VenuePageView } from "@/components/venues/VenuePageView";
import {
VenueRentalIndexView,
venueRentalIndexQuery,
} from "@/components/venues/VenueRentalIndexView";
import {
EventCategory,
EventOrganizer,
eventsOverviewQuery,
} from "@/lib/event";
import { newsQuery } from "@/lib/news";
export const dynamic = "force-dynamic";
export const revalidate = 0;
const previewPageQuery = graphql(`
query previewPage($token: String!) {
page: page(token: $token) {
__typename
... on GenericPage { ...Generic }
... on StudioPage { ...Studio }
... on SponsorsPage { ...SponsorsPage }
... on HomePage { ...Home }
... on EventPage { ...Event }
... on NewsPage { ...News }
... on AssociationPage { ...Association }
... on VenuePage { ...Venue }
... on NewsIndex { ...NewsIndex }
... on AssociationIndex { ...AssociationIndex }
... on VenueIndex { ...VenueIndex }
... on VenueRentalIndex { ...VenueRentalIndex }
... on ContactIndex { ...ContactIndex }
}
}
`);
function ExpiredPreview() {
return (
<main className="site-main" id="main">
<h1>Preview session expired</h1>
<p>Click Preview again in the Wagtail admin to start a new session.</p>
</main>
);
}
function UnsupportedType({ typename }: { typename: string }) {
return (
<main className="site-main" id="main">
<h1>Preview not available</h1>
<p>
Type <code>{typename}</code> cannot be previewed.
</p>
</main>
);
}
export default async function PreviewRender() {
const token = (await cookies()).get("preview-token")?.value;
if (!token) {
return <ExpiredPreview />;
}
const { data, error } = await getClient().query(previewPageQuery, { token });
if (error) {
throw new Error(error.message);
}
if (!data?.page) {
return <ExpiredPreview />;
}
const page = data.page;
switch (page.__typename) {
case "GenericPage":
return <GenericPageView page={page as GenericFragment} />;
case "StudioPage":
return <StudioPageView page={page as StudioFragment} />;
case "SponsorsPage":
return <SponsorsPageView page={page as SponsorsPageFragment} />;
case "EventPage":
return <EventPageView event={page as EventFragment} />;
case "NewsPage":
return <NewsPageView news={page as NewsFragment} />;
case "AssociationPage":
return <AssociationPageView association={page as AssociationFragment} />;
case "VenuePage":
return <VenuePageView venue={page as VenueFragment} />;
case "HomePage": {
const { data: aux } = await getClient().query(homeQuery, {});
const events = (aux?.events?.futureEvents ?? []) as EventFragment[];
const news = (aux?.news ?? []) as NewsFragment[];
return (
<HomePageView home={page as HomeFragment} events={events} news={news} />
);
}
case "EventIndex": {
const { data: aux } = await getClient().query(eventsOverviewQuery, {});
const events = (aux?.events?.futureEvents ?? []) as EventFragment[];
const eventCategories = (aux?.eventCategories ?? []) as EventCategory[];
const eventOrganizers = (aux?.eventOrganizers ?? []) as EventOrganizer[];
const venues = (aux?.venues ?? []) as VenueFragment[];
return (
<EventIndexView
events={events}
eventCategories={eventCategories}
eventOrganizers={eventOrganizers}
venues={venues}
/>
);
}
case "NewsIndex": {
const { data: aux } = await getClient().query(newsQuery, {});
const news = (aux?.news ?? []) as NewsFragment[];
return <NewsIndexView index={page as NewsIndexFragment} news={news} />;
}
case "AssociationIndex": {
const { data: aux } = await getClient().query(allAssociationsQuery, {});
const associations = (aux?.associations ?? []) as AssociationFragment[];
return (
<AssociationIndexView
index={page as AssociationIndexFragment}
associations={associations}
/>
);
}
case "VenueIndex": {
const { data: aux } = await getClient().query(venueIndexQuery, {});
const venues = (aux?.venues ?? []) as VenueFragment[];
return (
<VenueIndexView index={page as VenueIndexFragment} venues={venues} />
);
}
case "VenueRentalIndex": {
const { data: aux } = await getClient().query(venueRentalIndexQuery, {});
const venues = (aux?.venues ?? []) as VenueFragment[];
return (
<VenueRentalIndexView
index={page as VenueRentalIndexFragment}
venues={venues}
/>
);
}
case "ContactIndex":
return <ContactIndexView index={page as ContactIndexFragment} />;
default:
return <UnsupportedType typename={page.__typename ?? "unknown"} />;
}
}
@@ -0,0 +1,21 @@
"use client";
import styles from "./previewBanner.module.scss";
export function PreviewBanner() {
return (
<div className={styles.previewBanner} role="status">
<span className={styles.label}>Forhåndsvisning</span>
<button
type="button"
className="tertiary"
onClick={async () => {
await fetch("/api/preview/disable", { method: "POST" });
window.location.reload();
}}
>
Avslutt forhåndsvisning
</button>
</div>
);
}
@@ -0,0 +1,21 @@
.previewBanner {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 9999;
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--spacing-s);
padding: var(--spacing-xs) var(--spacing-s);
background: var(--color-deepBrick);
color: var(--color-betongGray);
font-family: var(--font-main-demi);
font-size: var(--font-size-caption);
}
.label {
text-transform: uppercase;
letter-spacing: 0.05em;
}
+24 -18
View File
@@ -19,8 +19,9 @@ type Documents = {
"\n query allEventSlugs {\n pages(contentType: \"events.EventPage\") {\n id\n slug\n }\n }\n ": typeof types.AllEventSlugsDocument, "\n query allEventSlugs {\n pages(contentType: \"events.EventPage\") {\n id\n slug\n }\n }\n ": typeof types.AllEventSlugsDocument,
"\n query allAssociationSlugs {\n pages(contentType: \"associations.AssociationPage\") {\n id\n slug\n }\n }\n ": typeof types.AllAssociationSlugsDocument, "\n query allAssociationSlugs {\n pages(contentType: \"associations.AssociationPage\") {\n id\n slug\n }\n }\n ": typeof types.AllAssociationSlugsDocument,
"\n query allVenueSlugs {\n pages(contentType: \"venues.VenuePage\", limit: 100) {\n id\n slug\n }\n }\n ": typeof types.AllVenueSlugsDocument, "\n query allVenueSlugs {\n pages(contentType: \"venues.VenuePage\", limit: 100) {\n id\n slug\n }\n }\n ": typeof types.AllVenueSlugsDocument,
"\n query previewPage($token: String!) {\n page: page(token: $token) {\n __typename\n ... on GenericPage { ...Generic }\n ... on StudioPage { ...Studio }\n ... on SponsorsPage { ...SponsorsPage }\n ... on HomePage { ...Home }\n ... on EventPage { ...Event }\n ... on NewsPage { ...News }\n ... on AssociationPage { ...Association }\n ... on VenuePage { ...Venue }\n ... on NewsIndex { ...NewsIndex }\n ... on AssociationIndex { ...AssociationIndex }\n ... on VenueIndex { ...VenueIndex }\n ... on VenueRentalIndex { ...VenueRentalIndex }\n ... on ContactIndex { ...ContactIndex }\n }\n }\n": typeof types.PreviewPageDocument,
"\n query search($query: String) {\n results: search(query: $query) {\n __typename\n ... on PageInterface {\n slug\n }\n ... on NewsPage {\n id\n title\n }\n ... on EventPage {\n id\n title\n }\n ... on GenericPage {\n id\n title\n }\n ... on VenuePage {\n id\n title\n }\n ... on AssociationPage {\n id\n title\n associationType\n }\n }\n }\n ": typeof types.SearchDocument, "\n query search($query: String) {\n results: search(query: $query) {\n __typename\n ... on PageInterface {\n slug\n }\n ... on NewsPage {\n id\n title\n }\n ... on EventPage {\n id\n title\n }\n ... on GenericPage {\n id\n title\n }\n ... on VenuePage {\n id\n title\n }\n ... on AssociationPage {\n id\n title\n associationType\n }\n }\n }\n ": typeof types.SearchDocument,
"\n fragment AssociationIndex on AssociationIndex {\n ... on AssociationIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n": typeof types.AssociationIndexFragmentDoc, "\n fragment AssociationIndex on AssociationIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n": typeof types.AssociationIndexFragmentDoc,
"\n fragment Association on AssociationPage {\n __typename\n id\n slug\n title\n seoTitle\n searchDescription\n excerpt\n lead\n body {\n ...Blocks\n }\n logo {\n url\n width\n height\n }\n associationType\n websiteUrl\n }\n": typeof types.AssociationFragmentDoc, "\n fragment Association on AssociationPage {\n __typename\n id\n slug\n title\n seoTitle\n searchDescription\n excerpt\n lead\n body {\n ...Blocks\n }\n logo {\n url\n width\n height\n }\n associationType\n websiteUrl\n }\n": typeof types.AssociationFragmentDoc,
"\n query allAssociations {\n index: associationIndex {\n ... on AssociationIndex {\n ...AssociationIndex\n }\n }\n associations: pages(\n contentType: \"associations.AssociationPage\"\n limit: 1000\n ) {\n ... on AssociationPage {\n ...Association\n }\n }\n }\n": typeof types.AllAssociationsDocument, "\n query allAssociations {\n index: associationIndex {\n ... on AssociationIndex {\n ...AssociationIndex\n }\n }\n associations: pages(\n contentType: \"associations.AssociationPage\"\n limit: 1000\n ) {\n ... on AssociationPage {\n ...Association\n }\n }\n }\n": typeof types.AllAssociationsDocument,
"\n query associationBySlug($slug: String!) {\n association: page(\n contentType: \"associations.AssociationPage\"\n slug: $slug\n ) {\n ... on AssociationPage {\n ...Association\n }\n }\n }\n": typeof types.AssociationBySlugDocument, "\n query associationBySlug($slug: String!) {\n association: page(\n contentType: \"associations.AssociationPage\"\n slug: $slug\n ) {\n ... on AssociationPage {\n ...Association\n }\n }\n }\n": typeof types.AssociationBySlugDocument,
@@ -38,24 +39,24 @@ type Documents = {
"\n fragment ImageWithTextBlock on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n": typeof types.ImageWithTextBlockFragmentDoc, "\n fragment ImageWithTextBlock on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n": typeof types.ImageWithTextBlockFragmentDoc,
"\n fragment PageSectionBlock on PageSectionBlock {\n title\n backgroundColor\n icon\n body {\n id\n blockType\n }\n }\n": typeof types.PageSectionBlockFragmentDoc, "\n fragment PageSectionBlock on PageSectionBlock {\n title\n backgroundColor\n icon\n body {\n id\n blockType\n }\n }\n": typeof types.PageSectionBlockFragmentDoc,
"\n fragment RichTextBlock on RichTextBlock {\n rawValue\n value\n }\n": typeof types.RichTextBlockFragmentDoc, "\n fragment RichTextBlock on RichTextBlock {\n rawValue\n value\n }\n": typeof types.RichTextBlockFragmentDoc,
"\n fragment ContactIndex on ContactIndex {\n ... on ContactIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n": typeof types.ContactIndexFragmentDoc, "\n fragment ContactIndex on ContactIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n": typeof types.ContactIndexFragmentDoc,
"\n query contacts {\n index: contactIndex {\n ... on ContactIndex {\n ...ContactIndex\n }\n }\n }\n": typeof types.ContactsDocument, "\n query contacts {\n index: contactIndex {\n ... on ContactIndex {\n ...ContactIndex\n }\n }\n }\n": typeof types.ContactsDocument,
"\n query eventBySlug($slug: String!) {\n event: page(contentType: \"events.EventPage\", slug: $slug) {\n ... on EventPage {\n ...Event\n }\n }\n }\n": typeof types.EventBySlugDocument, "\n query eventBySlug($slug: String!) {\n event: page(contentType: \"events.EventPage\", slug: $slug) {\n ... on EventPage {\n ...Event\n }\n }\n }\n": typeof types.EventBySlugDocument,
"\n fragment Generic on GenericPage {\n __typename\n id\n urlPath\n seoTitle\n searchDescription\n title\n lead\n pig\n body {\n ...Blocks\n }\n }\n": typeof types.GenericFragmentDoc, "\n fragment Generic on GenericPage {\n __typename\n id\n urlPath\n seoTitle\n searchDescription\n title\n lead\n pig\n body {\n ...Blocks\n }\n }\n": typeof types.GenericFragmentDoc,
"\n query genericPageByUrl($urlPath: String!) {\n page: page(contentType: \"generic.GenericPage\", urlPath: $urlPath) {\n ... on GenericPage {\n ...Generic\n }\n }\n }\n": typeof types.GenericPageByUrlDocument, "\n query genericPageByUrl($urlPath: String!) {\n page: page(contentType: \"generic.GenericPage\", urlPath: $urlPath) {\n ... on GenericPage {\n ...Generic\n }\n }\n }\n": typeof types.GenericPageByUrlDocument,
"\n fragment Home on HomePage {\n ... on HomePage {\n featuredEvents {\n id\n }\n }\n }\n": typeof types.HomeFragmentDoc, "\n fragment Home on HomePage {\n __typename\n featuredEvents {\n id\n }\n }\n": typeof types.HomeFragmentDoc,
"\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 news: pages(contentType: \"news.newsPage\", order: \"-first_published_at\", limit: 4) {\n ... on NewsPage {\n ...News\n }\n }\n }\n": typeof 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 news: pages(contentType: \"news.newsPage\", order: \"-first_published_at\", limit: 4) {\n ... on NewsPage {\n ...News\n }\n }\n }\n": typeof types.HomeDocument,
"\n query newsBySlug($slug: String!) {\n news: page(contentType: \"news.NewsPage\", slug: $slug) {\n ... on NewsPage {\n ...News\n }\n }\n }\n": typeof types.NewsBySlugDocument, "\n query newsBySlug($slug: String!) {\n news: page(contentType: \"news.NewsPage\", slug: $slug) {\n ... on NewsPage {\n ...News\n }\n }\n }\n": typeof types.NewsBySlugDocument,
"\n fragment Sponsor on SponsorBlock {\n id\n name\n logo {\n ...Image\n }\n text\n website\n }\n": typeof types.SponsorFragmentDoc, "\n fragment Sponsor on SponsorBlock {\n id\n name\n logo {\n ...Image\n }\n text\n website\n }\n": typeof types.SponsorFragmentDoc,
"\n fragment SponsorsPage on SponsorsPage {\n ... on SponsorsPage {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n sponsors {\n ... on SponsorBlock {\n ...Sponsor\n }\n }\n }\n }\n": typeof types.SponsorsPageFragmentDoc, "\n fragment SponsorsPage on SponsorsPage {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n sponsors {\n ... on SponsorBlock {\n ...Sponsor\n }\n }\n }\n": typeof types.SponsorsPageFragmentDoc,
"\n query sponsors {\n page: sponsorsPage {\n ... on SponsorsPage {\n ...SponsorsPage\n }\n }\n }\n": typeof types.SponsorsDocument, "\n query sponsors {\n page: sponsorsPage {\n ... on SponsorsPage {\n ...SponsorsPage\n }\n }\n }\n": typeof types.SponsorsDocument,
"\n fragment Studio on StudioPage {\n __typename\n id\n title\n seoTitle\n searchDescription\n lead\n pig\n logo {\n url\n width\n height\n alt\n }\n body {\n ...Blocks\n }\n }\n": typeof types.StudioFragmentDoc, "\n fragment Studio on StudioPage {\n __typename\n id\n title\n seoTitle\n searchDescription\n lead\n pig\n logo {\n url\n width\n height\n alt\n }\n body {\n ...Blocks\n }\n }\n": typeof types.StudioFragmentDoc,
"\n query studio {\n page: studioPage {\n ... on StudioPage {\n ...Studio\n }\n }\n }\n": typeof types.StudioDocument, "\n query studio {\n page: studioPage {\n ... on StudioPage {\n ...Studio\n }\n }\n }\n": typeof types.StudioDocument,
"\n fragment VenueIndex on VenueIndex {\n ... on VenueIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n": typeof types.VenueIndexFragmentDoc, "\n fragment VenueIndex on VenueIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n": typeof types.VenueIndexFragmentDoc,
"\n fragment Venue on VenuePage {\n __typename\n id\n slug\n title\n seoTitle\n searchDescription\n images {\n __typename\n ... on ImageSliderBlock {\n ...ImageSliderBlock\n }\n }\n body {\n ...Blocks\n }\n featuredImage {\n ...Image\n }\n showAsBookable\n showInOverview\n floor\n preposition\n usedFor\n techSpecsUrl\n capabilityAudio\n capabilityAudioVideo\n capabilityBar\n capabilityLighting\n capacityLegal\n capacityStanding\n capacitySitting\n }\n": typeof types.VenueFragmentDoc, "\n fragment Venue on VenuePage {\n __typename\n id\n slug\n title\n seoTitle\n searchDescription\n images {\n __typename\n ... on ImageSliderBlock {\n ...ImageSliderBlock\n }\n }\n body {\n ...Blocks\n }\n featuredImage {\n ...Image\n }\n showAsBookable\n showInOverview\n floor\n preposition\n usedFor\n techSpecsUrl\n capabilityAudio\n capabilityAudioVideo\n capabilityBar\n capabilityLighting\n capacityLegal\n capacityStanding\n capacitySitting\n }\n": typeof types.VenueFragmentDoc,
"\n query venueIndex {\n index: venueIndex {\n ... on VenueIndex {\n ...VenueIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\", limit: 100) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": typeof types.VenueIndexDocument, "\n query venueIndex {\n index: venueIndex {\n ... on VenueIndex {\n ...VenueIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\", limit: 100) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": typeof types.VenueIndexDocument,
"\n query venueBySlug($slug: String!) {\n venue: page(contentType: \"venues.VenuePage\", slug: $slug) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": typeof types.VenueBySlugDocument, "\n query venueBySlug($slug: String!) {\n venue: page(contentType: \"venues.VenuePage\", slug: $slug) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": typeof types.VenueBySlugDocument,
"\n fragment VenueRentalIndex on VenueRentalIndex {\n ... on VenueRentalIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n": typeof types.VenueRentalIndexFragmentDoc, "\n fragment VenueRentalIndex on VenueRentalIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n": typeof types.VenueRentalIndexFragmentDoc,
"\n query venueRentalIndex {\n index: venueRentalIndex {\n ... on VenueRentalIndex {\n ...VenueRentalIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\", limit: 100) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": typeof types.VenueRentalIndexDocument, "\n query venueRentalIndex {\n index: venueRentalIndex {\n ... on VenueRentalIndex {\n ...VenueRentalIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\", limit: 100) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": typeof types.VenueRentalIndexDocument,
"\n fragment LeafBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n ...RichTextBlock\n }\n ... on ImageWithTextBlock {\n ...ImageWithTextBlock\n }\n ... on ImageSliderBlock {\n ...ImageSliderBlock\n }\n ... on HorizontalRuleBlock {\n ...HorizontalRuleBlock\n }\n ... on FeaturedBlock {\n ...FeaturedBlock\n }\n ... on ContactListBlock {\n ...ContactListBlock\n }\n ... on EmbedBlock {\n ...EmbedBlock\n }\n ... on FactBoxBlock {\n ...FactBoxBlock\n }\n }\n": typeof types.LeafBlocksFragmentDoc, "\n fragment LeafBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n ...RichTextBlock\n }\n ... on ImageWithTextBlock {\n ...ImageWithTextBlock\n }\n ... on ImageSliderBlock {\n ...ImageSliderBlock\n }\n ... on HorizontalRuleBlock {\n ...HorizontalRuleBlock\n }\n ... on FeaturedBlock {\n ...FeaturedBlock\n }\n ... on ContactListBlock {\n ...ContactListBlock\n }\n ... on EmbedBlock {\n ...EmbedBlock\n }\n ... on FactBoxBlock {\n ...FactBoxBlock\n }\n }\n": typeof types.LeafBlocksFragmentDoc,
"\n fragment OneLevelOfBlocks on StreamFieldInterface {\n ...LeafBlocks\n ... on AccordionBlock {\n ...AccordionBlock\n body {\n ...LeafBlocks\n }\n }\n ... on PageSectionBlock {\n ...PageSectionBlock\n body {\n ...LeafBlocks\n }\n }\n }\n": typeof types.OneLevelOfBlocksFragmentDoc, "\n fragment OneLevelOfBlocks on StreamFieldInterface {\n ...LeafBlocks\n ... on AccordionBlock {\n ...AccordionBlock\n body {\n ...LeafBlocks\n }\n }\n ... on PageSectionBlock {\n ...PageSectionBlock\n body {\n ...LeafBlocks\n }\n }\n }\n": typeof types.OneLevelOfBlocksFragmentDoc,
@@ -82,8 +83,9 @@ const documents: Documents = {
"\n query allEventSlugs {\n pages(contentType: \"events.EventPage\") {\n id\n slug\n }\n }\n ": types.AllEventSlugsDocument, "\n query allEventSlugs {\n pages(contentType: \"events.EventPage\") {\n id\n slug\n }\n }\n ": types.AllEventSlugsDocument,
"\n query allAssociationSlugs {\n pages(contentType: \"associations.AssociationPage\") {\n id\n slug\n }\n }\n ": types.AllAssociationSlugsDocument, "\n query allAssociationSlugs {\n pages(contentType: \"associations.AssociationPage\") {\n id\n slug\n }\n }\n ": types.AllAssociationSlugsDocument,
"\n query allVenueSlugs {\n pages(contentType: \"venues.VenuePage\", limit: 100) {\n id\n slug\n }\n }\n ": types.AllVenueSlugsDocument, "\n query allVenueSlugs {\n pages(contentType: \"venues.VenuePage\", limit: 100) {\n id\n slug\n }\n }\n ": types.AllVenueSlugsDocument,
"\n query previewPage($token: String!) {\n page: page(token: $token) {\n __typename\n ... on GenericPage { ...Generic }\n ... on StudioPage { ...Studio }\n ... on SponsorsPage { ...SponsorsPage }\n ... on HomePage { ...Home }\n ... on EventPage { ...Event }\n ... on NewsPage { ...News }\n ... on AssociationPage { ...Association }\n ... on VenuePage { ...Venue }\n ... on NewsIndex { ...NewsIndex }\n ... on AssociationIndex { ...AssociationIndex }\n ... on VenueIndex { ...VenueIndex }\n ... on VenueRentalIndex { ...VenueRentalIndex }\n ... on ContactIndex { ...ContactIndex }\n }\n }\n": types.PreviewPageDocument,
"\n query search($query: String) {\n results: search(query: $query) {\n __typename\n ... on PageInterface {\n slug\n }\n ... on NewsPage {\n id\n title\n }\n ... on EventPage {\n id\n title\n }\n ... on GenericPage {\n id\n title\n }\n ... on VenuePage {\n id\n title\n }\n ... on AssociationPage {\n id\n title\n associationType\n }\n }\n }\n ": types.SearchDocument, "\n query search($query: String) {\n results: search(query: $query) {\n __typename\n ... on PageInterface {\n slug\n }\n ... on NewsPage {\n id\n title\n }\n ... on EventPage {\n id\n title\n }\n ... on GenericPage {\n id\n title\n }\n ... on VenuePage {\n id\n title\n }\n ... on AssociationPage {\n id\n title\n associationType\n }\n }\n }\n ": types.SearchDocument,
"\n fragment AssociationIndex on AssociationIndex {\n ... on AssociationIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n": types.AssociationIndexFragmentDoc, "\n fragment AssociationIndex on AssociationIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n": types.AssociationIndexFragmentDoc,
"\n fragment Association on AssociationPage {\n __typename\n id\n slug\n title\n seoTitle\n searchDescription\n excerpt\n lead\n body {\n ...Blocks\n }\n logo {\n url\n width\n height\n }\n associationType\n websiteUrl\n }\n": types.AssociationFragmentDoc, "\n fragment Association on AssociationPage {\n __typename\n id\n slug\n title\n seoTitle\n searchDescription\n excerpt\n lead\n body {\n ...Blocks\n }\n logo {\n url\n width\n height\n }\n associationType\n websiteUrl\n }\n": types.AssociationFragmentDoc,
"\n query allAssociations {\n index: associationIndex {\n ... on AssociationIndex {\n ...AssociationIndex\n }\n }\n associations: pages(\n contentType: \"associations.AssociationPage\"\n limit: 1000\n ) {\n ... on AssociationPage {\n ...Association\n }\n }\n }\n": types.AllAssociationsDocument, "\n query allAssociations {\n index: associationIndex {\n ... on AssociationIndex {\n ...AssociationIndex\n }\n }\n associations: pages(\n contentType: \"associations.AssociationPage\"\n limit: 1000\n ) {\n ... on AssociationPage {\n ...Association\n }\n }\n }\n": types.AllAssociationsDocument,
"\n query associationBySlug($slug: String!) {\n association: page(\n contentType: \"associations.AssociationPage\"\n slug: $slug\n ) {\n ... on AssociationPage {\n ...Association\n }\n }\n }\n": types.AssociationBySlugDocument, "\n query associationBySlug($slug: String!) {\n association: page(\n contentType: \"associations.AssociationPage\"\n slug: $slug\n ) {\n ... on AssociationPage {\n ...Association\n }\n }\n }\n": types.AssociationBySlugDocument,
@@ -101,24 +103,24 @@ const documents: Documents = {
"\n fragment ImageWithTextBlock on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n": types.ImageWithTextBlockFragmentDoc, "\n fragment ImageWithTextBlock on ImageWithTextBlock {\n image {\n ...Image\n }\n imageFormat\n text\n }\n": types.ImageWithTextBlockFragmentDoc,
"\n fragment PageSectionBlock on PageSectionBlock {\n title\n backgroundColor\n icon\n body {\n id\n blockType\n }\n }\n": types.PageSectionBlockFragmentDoc, "\n fragment PageSectionBlock on PageSectionBlock {\n title\n backgroundColor\n icon\n body {\n id\n blockType\n }\n }\n": types.PageSectionBlockFragmentDoc,
"\n fragment RichTextBlock on RichTextBlock {\n rawValue\n value\n }\n": types.RichTextBlockFragmentDoc, "\n fragment RichTextBlock on RichTextBlock {\n rawValue\n value\n }\n": types.RichTextBlockFragmentDoc,
"\n fragment ContactIndex on ContactIndex {\n ... on ContactIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n": types.ContactIndexFragmentDoc, "\n fragment ContactIndex on ContactIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n": types.ContactIndexFragmentDoc,
"\n query contacts {\n index: contactIndex {\n ... on ContactIndex {\n ...ContactIndex\n }\n }\n }\n": types.ContactsDocument, "\n query contacts {\n index: contactIndex {\n ... on ContactIndex {\n ...ContactIndex\n }\n }\n }\n": types.ContactsDocument,
"\n query eventBySlug($slug: String!) {\n event: page(contentType: \"events.EventPage\", slug: $slug) {\n ... on EventPage {\n ...Event\n }\n }\n }\n": types.EventBySlugDocument, "\n query eventBySlug($slug: String!) {\n event: page(contentType: \"events.EventPage\", slug: $slug) {\n ... on EventPage {\n ...Event\n }\n }\n }\n": types.EventBySlugDocument,
"\n fragment Generic on GenericPage {\n __typename\n id\n urlPath\n seoTitle\n searchDescription\n title\n lead\n pig\n body {\n ...Blocks\n }\n }\n": types.GenericFragmentDoc, "\n fragment Generic on GenericPage {\n __typename\n id\n urlPath\n seoTitle\n searchDescription\n title\n lead\n pig\n body {\n ...Blocks\n }\n }\n": types.GenericFragmentDoc,
"\n query genericPageByUrl($urlPath: String!) {\n page: page(contentType: \"generic.GenericPage\", urlPath: $urlPath) {\n ... on GenericPage {\n ...Generic\n }\n }\n }\n": types.GenericPageByUrlDocument, "\n query genericPageByUrl($urlPath: String!) {\n page: page(contentType: \"generic.GenericPage\", urlPath: $urlPath) {\n ... on GenericPage {\n ...Generic\n }\n }\n }\n": types.GenericPageByUrlDocument,
"\n fragment Home on HomePage {\n ... on HomePage {\n featuredEvents {\n id\n }\n }\n }\n": types.HomeFragmentDoc, "\n fragment Home on HomePage {\n __typename\n featuredEvents {\n id\n }\n }\n": types.HomeFragmentDoc,
"\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 news: pages(contentType: \"news.newsPage\", order: \"-first_published_at\", limit: 4) {\n ... on NewsPage {\n ...News\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 news: pages(contentType: \"news.newsPage\", order: \"-first_published_at\", limit: 4) {\n ... on NewsPage {\n ...News\n }\n }\n }\n": types.HomeDocument,
"\n query newsBySlug($slug: String!) {\n news: page(contentType: \"news.NewsPage\", slug: $slug) {\n ... on NewsPage {\n ...News\n }\n }\n }\n": types.NewsBySlugDocument, "\n query newsBySlug($slug: String!) {\n news: page(contentType: \"news.NewsPage\", slug: $slug) {\n ... on NewsPage {\n ...News\n }\n }\n }\n": types.NewsBySlugDocument,
"\n fragment Sponsor on SponsorBlock {\n id\n name\n logo {\n ...Image\n }\n text\n website\n }\n": types.SponsorFragmentDoc, "\n fragment Sponsor on SponsorBlock {\n id\n name\n logo {\n ...Image\n }\n text\n website\n }\n": types.SponsorFragmentDoc,
"\n fragment SponsorsPage on SponsorsPage {\n ... on SponsorsPage {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n sponsors {\n ... on SponsorBlock {\n ...Sponsor\n }\n }\n }\n }\n": types.SponsorsPageFragmentDoc, "\n fragment SponsorsPage on SponsorsPage {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n sponsors {\n ... on SponsorBlock {\n ...Sponsor\n }\n }\n }\n": types.SponsorsPageFragmentDoc,
"\n query sponsors {\n page: sponsorsPage {\n ... on SponsorsPage {\n ...SponsorsPage\n }\n }\n }\n": types.SponsorsDocument, "\n query sponsors {\n page: sponsorsPage {\n ... on SponsorsPage {\n ...SponsorsPage\n }\n }\n }\n": types.SponsorsDocument,
"\n fragment Studio on StudioPage {\n __typename\n id\n title\n seoTitle\n searchDescription\n lead\n pig\n logo {\n url\n width\n height\n alt\n }\n body {\n ...Blocks\n }\n }\n": types.StudioFragmentDoc, "\n fragment Studio on StudioPage {\n __typename\n id\n title\n seoTitle\n searchDescription\n lead\n pig\n logo {\n url\n width\n height\n alt\n }\n body {\n ...Blocks\n }\n }\n": types.StudioFragmentDoc,
"\n query studio {\n page: studioPage {\n ... on StudioPage {\n ...Studio\n }\n }\n }\n": types.StudioDocument, "\n query studio {\n page: studioPage {\n ... on StudioPage {\n ...Studio\n }\n }\n }\n": types.StudioDocument,
"\n fragment VenueIndex on VenueIndex {\n ... on VenueIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n": types.VenueIndexFragmentDoc, "\n fragment VenueIndex on VenueIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n": types.VenueIndexFragmentDoc,
"\n fragment Venue on VenuePage {\n __typename\n id\n slug\n title\n seoTitle\n searchDescription\n images {\n __typename\n ... on ImageSliderBlock {\n ...ImageSliderBlock\n }\n }\n body {\n ...Blocks\n }\n featuredImage {\n ...Image\n }\n showAsBookable\n showInOverview\n floor\n preposition\n usedFor\n techSpecsUrl\n capabilityAudio\n capabilityAudioVideo\n capabilityBar\n capabilityLighting\n capacityLegal\n capacityStanding\n capacitySitting\n }\n": types.VenueFragmentDoc, "\n fragment Venue on VenuePage {\n __typename\n id\n slug\n title\n seoTitle\n searchDescription\n images {\n __typename\n ... on ImageSliderBlock {\n ...ImageSliderBlock\n }\n }\n body {\n ...Blocks\n }\n featuredImage {\n ...Image\n }\n showAsBookable\n showInOverview\n floor\n preposition\n usedFor\n techSpecsUrl\n capabilityAudio\n capabilityAudioVideo\n capabilityBar\n capabilityLighting\n capacityLegal\n capacityStanding\n capacitySitting\n }\n": types.VenueFragmentDoc,
"\n query venueIndex {\n index: venueIndex {\n ... on VenueIndex {\n ...VenueIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\", limit: 100) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": types.VenueIndexDocument, "\n query venueIndex {\n index: venueIndex {\n ... on VenueIndex {\n ...VenueIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\", limit: 100) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": types.VenueIndexDocument,
"\n query venueBySlug($slug: String!) {\n venue: page(contentType: \"venues.VenuePage\", slug: $slug) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": types.VenueBySlugDocument, "\n query venueBySlug($slug: String!) {\n venue: page(contentType: \"venues.VenuePage\", slug: $slug) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": types.VenueBySlugDocument,
"\n fragment VenueRentalIndex on VenueRentalIndex {\n ... on VenueRentalIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n": types.VenueRentalIndexFragmentDoc, "\n fragment VenueRentalIndex on VenueRentalIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n": types.VenueRentalIndexFragmentDoc,
"\n query venueRentalIndex {\n index: venueRentalIndex {\n ... on VenueRentalIndex {\n ...VenueRentalIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\", limit: 100) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": types.VenueRentalIndexDocument, "\n query venueRentalIndex {\n index: venueRentalIndex {\n ... on VenueRentalIndex {\n ...VenueRentalIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\", limit: 100) {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n": types.VenueRentalIndexDocument,
"\n fragment LeafBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n ...RichTextBlock\n }\n ... on ImageWithTextBlock {\n ...ImageWithTextBlock\n }\n ... on ImageSliderBlock {\n ...ImageSliderBlock\n }\n ... on HorizontalRuleBlock {\n ...HorizontalRuleBlock\n }\n ... on FeaturedBlock {\n ...FeaturedBlock\n }\n ... on ContactListBlock {\n ...ContactListBlock\n }\n ... on EmbedBlock {\n ...EmbedBlock\n }\n ... on FactBoxBlock {\n ...FactBoxBlock\n }\n }\n": types.LeafBlocksFragmentDoc, "\n fragment LeafBlocks on StreamFieldInterface {\n id\n blockType\n field\n ... on RichTextBlock {\n ...RichTextBlock\n }\n ... on ImageWithTextBlock {\n ...ImageWithTextBlock\n }\n ... on ImageSliderBlock {\n ...ImageSliderBlock\n }\n ... on HorizontalRuleBlock {\n ...HorizontalRuleBlock\n }\n ... on FeaturedBlock {\n ...FeaturedBlock\n }\n ... on ContactListBlock {\n ...ContactListBlock\n }\n ... on EmbedBlock {\n ...EmbedBlock\n }\n ... on FactBoxBlock {\n ...FactBoxBlock\n }\n }\n": types.LeafBlocksFragmentDoc,
"\n fragment OneLevelOfBlocks on StreamFieldInterface {\n ...LeafBlocks\n ... on AccordionBlock {\n ...AccordionBlock\n body {\n ...LeafBlocks\n }\n }\n ... on PageSectionBlock {\n ...PageSectionBlock\n body {\n ...LeafBlocks\n }\n }\n }\n": types.OneLevelOfBlocksFragmentDoc, "\n fragment OneLevelOfBlocks on StreamFieldInterface {\n ...LeafBlocks\n ... on AccordionBlock {\n ...AccordionBlock\n body {\n ...LeafBlocks\n }\n }\n ... on PageSectionBlock {\n ...PageSectionBlock\n body {\n ...LeafBlocks\n }\n }\n }\n": types.OneLevelOfBlocksFragmentDoc,
@@ -174,6 +176,10 @@ export function graphql(source: "\n query allAssociationSlugs {\n pages(
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * 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 allVenueSlugs {\n pages(contentType: \"venues.VenuePage\", limit: 100) {\n id\n slug\n }\n }\n "): (typeof documents)["\n query allVenueSlugs {\n pages(contentType: \"venues.VenuePage\", limit: 100) {\n id\n slug\n }\n }\n "]; export function graphql(source: "\n query allVenueSlugs {\n pages(contentType: \"venues.VenuePage\", limit: 100) {\n id\n slug\n }\n }\n "): (typeof documents)["\n query allVenueSlugs {\n pages(contentType: \"venues.VenuePage\", limit: 100) {\n id\n slug\n }\n }\n "];
/**
* 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 previewPage($token: String!) {\n page: page(token: $token) {\n __typename\n ... on GenericPage { ...Generic }\n ... on StudioPage { ...Studio }\n ... on SponsorsPage { ...SponsorsPage }\n ... on HomePage { ...Home }\n ... on EventPage { ...Event }\n ... on NewsPage { ...News }\n ... on AssociationPage { ...Association }\n ... on VenuePage { ...Venue }\n ... on NewsIndex { ...NewsIndex }\n ... on AssociationIndex { ...AssociationIndex }\n ... on VenueIndex { ...VenueIndex }\n ... on VenueRentalIndex { ...VenueRentalIndex }\n ... on ContactIndex { ...ContactIndex }\n }\n }\n"): (typeof documents)["\n query previewPage($token: String!) {\n page: page(token: $token) {\n __typename\n ... on GenericPage { ...Generic }\n ... on StudioPage { ...Studio }\n ... on SponsorsPage { ...SponsorsPage }\n ... on HomePage { ...Home }\n ... on EventPage { ...Event }\n ... on NewsPage { ...News }\n ... on AssociationPage { ...Association }\n ... on VenuePage { ...Venue }\n ... on NewsIndex { ...NewsIndex }\n ... on AssociationIndex { ...AssociationIndex }\n ... on VenueIndex { ...VenueIndex }\n ... on VenueRentalIndex { ...VenueRentalIndex }\n ... on ContactIndex { ...ContactIndex }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
@@ -181,7 +187,7 @@ export function graphql(source: "\n query search($query: String) {\n
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n fragment AssociationIndex on AssociationIndex {\n ... on AssociationIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n"): (typeof documents)["\n fragment AssociationIndex on AssociationIndex {\n ... on AssociationIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n"]; export function graphql(source: "\n fragment AssociationIndex on AssociationIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n"): (typeof documents)["\n fragment AssociationIndex on AssociationIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
@@ -253,7 +259,7 @@ export function graphql(source: "\n fragment RichTextBlock on RichTextBlock {\n
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n fragment ContactIndex on ContactIndex {\n ... on ContactIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n"): (typeof documents)["\n fragment ContactIndex on ContactIndex {\n ... on ContactIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n"]; export function graphql(source: "\n fragment ContactIndex on ContactIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n"): (typeof documents)["\n fragment ContactIndex on ContactIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
@@ -273,7 +279,7 @@ export function graphql(source: "\n query genericPageByUrl($urlPath: String!) {
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n fragment Home on HomePage {\n ... on HomePage {\n featuredEvents {\n id\n }\n }\n }\n"): (typeof documents)["\n fragment Home on HomePage {\n ... on HomePage {\n featuredEvents {\n id\n }\n }\n }\n"]; export function graphql(source: "\n fragment Home on HomePage {\n __typename\n featuredEvents {\n id\n }\n }\n"): (typeof documents)["\n fragment Home on HomePage {\n __typename\n featuredEvents {\n id\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
@@ -289,7 +295,7 @@ export function graphql(source: "\n fragment Sponsor on SponsorBlock {\n id\
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n fragment SponsorsPage on SponsorsPage {\n ... on SponsorsPage {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n sponsors {\n ... on SponsorBlock {\n ...Sponsor\n }\n }\n }\n }\n"): (typeof documents)["\n fragment SponsorsPage on SponsorsPage {\n ... on SponsorsPage {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n sponsors {\n ... on SponsorBlock {\n ...Sponsor\n }\n }\n }\n }\n"]; export function graphql(source: "\n fragment SponsorsPage on SponsorsPage {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n sponsors {\n ... on SponsorBlock {\n ...Sponsor\n }\n }\n }\n"): (typeof documents)["\n fragment SponsorsPage on SponsorsPage {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n sponsors {\n ... on SponsorBlock {\n ...Sponsor\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
@@ -305,7 +311,7 @@ export function graphql(source: "\n query studio {\n page: studioPage {\n
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n fragment VenueIndex on VenueIndex {\n ... on VenueIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n"): (typeof documents)["\n fragment VenueIndex on VenueIndex {\n ... on VenueIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n"]; export function graphql(source: "\n fragment VenueIndex on VenueIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n"): (typeof documents)["\n fragment VenueIndex on VenueIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
@@ -321,7 +327,7 @@ export function graphql(source: "\n query venueBySlug($slug: String!) {\n ve
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n fragment VenueRentalIndex on VenueRentalIndex {\n ... on VenueRentalIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n"): (typeof documents)["\n fragment VenueRentalIndex on VenueRentalIndex {\n ... on VenueRentalIndex {\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n }\n"]; export function graphql(source: "\n fragment VenueRentalIndex on VenueRentalIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n"): (typeof documents)["\n fragment VenueRentalIndex on VenueRentalIndex {\n __typename\n title\n seoTitle\n searchDescription\n lead\n body {\n ...Blocks\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
+82 -19
View File
File diff suppressed because one or more lines are too long