add some basic search functionality
This commit is contained in:
@ -9,6 +9,7 @@ from grapple.models import (
|
|||||||
from wagtail.admin.panels import FieldPanel
|
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 dnscms.fields import CommonStreamField
|
from dnscms.fields import CommonStreamField
|
||||||
|
|
||||||
@ -32,6 +33,8 @@ class AssociationIndex(Page):
|
|||||||
GraphQLStreamfield("body"),
|
GraphQLStreamfield("body"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = Page.search_fields
|
||||||
|
|
||||||
|
|
||||||
class AssociationPage(Page):
|
class AssociationPage(Page):
|
||||||
subpage_types = []
|
subpage_types = []
|
||||||
@ -75,3 +78,8 @@ class AssociationPage(Page):
|
|||||||
GraphQLString("website_url"),
|
GraphQLString("website_url"),
|
||||||
GraphQLString("association_type"),
|
GraphQLString("association_type"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = Page.search_fields + [
|
||||||
|
index.SearchField("excerpt"),
|
||||||
|
index.SearchField("body"),
|
||||||
|
]
|
||||||
|
@ -9,6 +9,7 @@ from wagtail.admin.panels import (
|
|||||||
)
|
)
|
||||||
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.snippets.models import register_snippet
|
from wagtail.snippets.models import register_snippet
|
||||||
|
|
||||||
from contacts.blocks import ContactSectionBlock
|
from contacts.blocks import ContactSectionBlock
|
||||||
@ -37,6 +38,8 @@ class ContactIndex(Page):
|
|||||||
|
|
||||||
graphql_fields = [GraphQLRichText("lead"), GraphQLStreamfield("body")]
|
graphql_fields = [GraphQLRichText("lead"), GraphQLStreamfield("body")]
|
||||||
|
|
||||||
|
search_fields = Page.search_fields + [index.SearchField("body")]
|
||||||
|
|
||||||
|
|
||||||
@register_snippet
|
@register_snippet
|
||||||
@register_query_field("contactEntity", "contactEntities")
|
@register_query_field("contactEntity", "contactEntities")
|
||||||
|
@ -25,6 +25,7 @@ from wagtail.admin.panels import (
|
|||||||
TitleFieldPanel,
|
TitleFieldPanel,
|
||||||
)
|
)
|
||||||
from wagtail.models import Orderable, Page, PageManager, PageQuerySet
|
from wagtail.models import Orderable, Page, PageManager, PageQuerySet
|
||||||
|
from wagtail.search import index
|
||||||
from wagtail.snippets.models import register_snippet
|
from wagtail.snippets.models import register_snippet
|
||||||
|
|
||||||
from associations.widgets import AssociationChooserWidget
|
from associations.widgets import AssociationChooserWidget
|
||||||
@ -65,6 +66,8 @@ class EventIndex(Page):
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = []
|
||||||
|
|
||||||
|
|
||||||
@register_snippet
|
@register_snippet
|
||||||
@register_query_field("eventCategory", "eventCategories")
|
@register_query_field("eventCategory", "eventCategories")
|
||||||
@ -374,6 +377,8 @@ class EventPage(Page):
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = Page.search_fields + [index.SearchField("body")]
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ from grapple.models import GraphQLRichText, GraphQLStreamfield
|
|||||||
from wagtail.admin.panels import FieldPanel
|
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 dnscms.blocks import PageSectionBlock
|
from dnscms.blocks import PageSectionBlock
|
||||||
from dnscms.fields import BASE_BLOCKS
|
from dnscms.fields import BASE_BLOCKS
|
||||||
@ -23,3 +24,5 @@ class GenericPage(Page):
|
|||||||
GraphQLRichText("lead"),
|
GraphQLRichText("lead"),
|
||||||
GraphQLStreamfield("body"),
|
GraphQLStreamfield("body"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = Page.search_fields + [index.SearchField("lead"), index.SearchField("body")]
|
||||||
|
@ -30,6 +30,8 @@ class HomePage(Page):
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = []
|
||||||
|
|
||||||
|
|
||||||
class HomePageFeaturedEvents(ClusterableModel, Orderable):
|
class HomePageFeaturedEvents(ClusterableModel, Orderable):
|
||||||
parent = ParentalKey("home.HomePage", related_name="featured_events")
|
parent = ParentalKey("home.HomePage", related_name="featured_events")
|
||||||
|
@ -43,6 +43,8 @@ class CustomImage(AbstractImage):
|
|||||||
GraphQLString("attribution"),
|
GraphQLString("attribution"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = []
|
||||||
|
|
||||||
|
|
||||||
class Rendition(AbstractRendition):
|
class Rendition(AbstractRendition):
|
||||||
image = models.ForeignKey(CustomImage, on_delete=models.CASCADE, related_name="renditions")
|
image = models.ForeignKey(CustomImage, on_delete=models.CASCADE, related_name="renditions")
|
||||||
|
@ -4,6 +4,7 @@ from grapple.models import GraphQLImage, GraphQLRichText, GraphQLStreamfield, Gr
|
|||||||
from wagtail.admin.panels import FieldPanel
|
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 dnscms.fields import CommonStreamField
|
from dnscms.fields import CommonStreamField
|
||||||
|
|
||||||
@ -23,6 +24,8 @@ class NewsIndex(Page):
|
|||||||
GraphQLRichText("lead"),
|
GraphQLRichText("lead"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = []
|
||||||
|
|
||||||
|
|
||||||
class NewsPage(Page):
|
class NewsPage(Page):
|
||||||
subpage_types = []
|
subpage_types = []
|
||||||
@ -65,3 +68,9 @@ class NewsPage(Page):
|
|||||||
GraphQLStreamfield("body"),
|
GraphQLStreamfield("body"),
|
||||||
GraphQLImage("featured_image"),
|
GraphQLImage("featured_image"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = Page.search_fields + [
|
||||||
|
index.SearchField("excerpt", boost=1),
|
||||||
|
index.SearchField("lead", boost=1),
|
||||||
|
index.SearchField("body"),
|
||||||
|
]
|
||||||
|
@ -10,6 +10,7 @@ from grapple.models import (
|
|||||||
from wagtail.admin.panels import FieldPanel, FieldRowPanel, MultiFieldPanel
|
from wagtail.admin.panels import FieldPanel, FieldRowPanel, MultiFieldPanel
|
||||||
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 dnscms.fields import CommonStreamField
|
from dnscms.fields import CommonStreamField
|
||||||
|
|
||||||
@ -137,3 +138,8 @@ class VenuePage(Page):
|
|||||||
GraphQLString("capacity_standing"),
|
GraphQLString("capacity_standing"),
|
||||||
GraphQLString("capacity_sitting"),
|
GraphQLString("capacity_sitting"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
search_fields = Page.search_fields + [
|
||||||
|
index.SearchField("lead"),
|
||||||
|
index.SearchField("body"),
|
||||||
|
]
|
||||||
|
14
web/package-lock.json
generated
14
web/package-lock.json
generated
@ -23,7 +23,8 @@
|
|||||||
"react-intersection-observer": "^9.13.0",
|
"react-intersection-observer": "^9.13.0",
|
||||||
"sass": "^1.77.8",
|
"sass": "^1.77.8",
|
||||||
"swiper": "^11.1.4",
|
"swiper": "^11.1.4",
|
||||||
"urql": "^4.1.0"
|
"urql": "^4.1.0",
|
||||||
|
"use-debounce": "^10.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
@ -8306,6 +8307,17 @@
|
|||||||
"react": ">= 16.8.0"
|
"react": ">= 16.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-debounce": {
|
||||||
|
"version": "10.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.1.tgz",
|
||||||
|
"integrity": "sha512-0uUXjOfm44e6z4LZ/woZvkM8FwV1wiuoB6xnrrOmeAEjRDDzTLQNRFtYHvqUsJdrz1X37j0rVGIVp144GLHGKg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
"react-intersection-observer": "^9.13.0",
|
"react-intersection-observer": "^9.13.0",
|
||||||
"sass": "^1.77.8",
|
"sass": "^1.77.8",
|
||||||
"swiper": "^11.1.4",
|
"swiper": "^11.1.4",
|
||||||
"urql": "^4.1.0"
|
"urql": "^4.1.0",
|
||||||
|
"use-debounce": "^10.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
|
60
web/src/app/sok/page.tsx
Normal file
60
web/src/app/sok/page.tsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { graphql } from "@/gql";
|
||||||
|
import { getClient } from "@/app/client";
|
||||||
|
import { SearchContainer } from "@/components/search/SearchContainer";
|
||||||
|
import { Suspense } from "react";
|
||||||
|
|
||||||
|
export default async function Page({
|
||||||
|
searchParams,
|
||||||
|
}: {
|
||||||
|
searchParams?: {
|
||||||
|
q?: string;
|
||||||
|
};
|
||||||
|
}) {
|
||||||
|
const { q: query } = searchParams ?? {};
|
||||||
|
let results = [];
|
||||||
|
|
||||||
|
if (query) {
|
||||||
|
const searchQuery = graphql(`
|
||||||
|
query search($query: String) {
|
||||||
|
results: search(query: $query) {
|
||||||
|
__typename
|
||||||
|
... on NewsPage {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
}
|
||||||
|
... on EventPage {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
}
|
||||||
|
... on GenericPage {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
}
|
||||||
|
... on VenuePage {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
}
|
||||||
|
... on AssociationPage {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
associationType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
|
||||||
|
const { data, error } = await getClient().query(searchQuery, {
|
||||||
|
query: query,
|
||||||
|
});
|
||||||
|
|
||||||
|
results = (data?.results ?? []) as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className="site-main" id="main">
|
||||||
|
<Suspense key={query}>
|
||||||
|
<SearchContainer query={query ?? ""} results={results} />
|
||||||
|
</Suspense>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
@ -1,17 +1,19 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useState, useEffect, useRef } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname, useRouter } from "next/navigation";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import styles from "./header.module.scss";
|
import styles from "./header.module.scss";
|
||||||
import { Logo, LogoIcon } from "@/components/general/Logo";
|
import { Logo, LogoIcon } from "@/components/general/Logo";
|
||||||
import Icon from "../general/Icon";
|
import Icon from "../general/Icon";
|
||||||
import { useInView } from "react-intersection-observer";
|
import { useInView } from "react-intersection-observer";
|
||||||
|
import { getSearchPath } from "@/lib/common";
|
||||||
|
|
||||||
export const Header = () => {
|
export const Header = () => {
|
||||||
const { ref: observer, inView: isInView } = useInView({
|
const { ref: observer, inView: isInView } = useInView({
|
||||||
triggerOnce: false,
|
triggerOnce: false,
|
||||||
initialInView: true,
|
initialInView: true,
|
||||||
});
|
});
|
||||||
|
const { replace } = useRouter();
|
||||||
|
|
||||||
const [showMenu, setShowMenu] = useState(false);
|
const [showMenu, setShowMenu] = useState(false);
|
||||||
function toggleMenu() {
|
function toggleMenu() {
|
||||||
@ -42,6 +44,17 @@ export const Header = () => {
|
|||||||
undefined
|
undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleSearch = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
|
if (e.key != "Enter") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const query = e.currentTarget.value;
|
||||||
|
if (query) {
|
||||||
|
setShowMenu(false);
|
||||||
|
replace(getSearchPath(query));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<header
|
<header
|
||||||
@ -144,7 +157,7 @@ export const Header = () => {
|
|||||||
<li className={styles.search}>
|
<li className={styles.search}>
|
||||||
<label>
|
<label>
|
||||||
<p>Søk</p>
|
<p>Søk</p>
|
||||||
<input type="text" />
|
<input type="text" onKeyDown={handleSearch} />
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
<li className={styles.galtinn}>
|
<li className={styles.galtinn}>
|
||||||
|
74
web/src/components/search/SearchContainer.tsx
Normal file
74
web/src/components/search/SearchContainer.tsx
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
"use client";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
import { PageHeader } from "../general/PageHeader";
|
||||||
|
import { useSearchParams, usePathname, useRouter } from "next/navigation";
|
||||||
|
import { getSearchPath } from "@/lib/common";
|
||||||
|
export function SearchContainer({
|
||||||
|
query,
|
||||||
|
results,
|
||||||
|
}: {
|
||||||
|
query: string;
|
||||||
|
results: any;
|
||||||
|
}) {
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const pathname = usePathname();
|
||||||
|
const { replace } = useRouter();
|
||||||
|
|
||||||
|
const onQueryChange = useDebouncedCallback((query) => {
|
||||||
|
replace(getSearchPath(query));
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<PageHeader heading="Søk" />
|
||||||
|
<input
|
||||||
|
name="query"
|
||||||
|
type="text"
|
||||||
|
autoFocus
|
||||||
|
defaultValue={query ?? ""}
|
||||||
|
onChange={(e) => {
|
||||||
|
onQueryChange(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{query && <SearchResults results={results} />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function capitalizeFirstLetter(s: string) {
|
||||||
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PAGE_TYPES: Record<string, string> = {
|
||||||
|
NewsPage: "Nyhet",
|
||||||
|
EventPage: "Arrangement",
|
||||||
|
GenericPage: "Underside",
|
||||||
|
VenuePage: "Lokale",
|
||||||
|
AssociationPage: "Forening",
|
||||||
|
};
|
||||||
|
|
||||||
|
function SearchResults({ results }: { results: any }) {
|
||||||
|
if (!results.length) {
|
||||||
|
return <div>Ingen resultater 😔</div>;
|
||||||
|
}
|
||||||
|
const supportedResults = results.filter(
|
||||||
|
(result: any) =>
|
||||||
|
!!result?.id && Object.keys(PAGE_TYPES).includes(result.__typename)
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{supportedResults.map((result: any) => {
|
||||||
|
let resultType = PAGE_TYPES[result.__typename] ?? "";
|
||||||
|
if (result.__typename === "AssociationPage") {
|
||||||
|
resultType = capitalizeFirstLetter(result?.associationType);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div key={result.id}>
|
||||||
|
<span>{resultType}</span>
|
||||||
|
<span>{result.title}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -34,6 +34,7 @@ const documents = {
|
|||||||
"\n query venueIndex {\n index: venueIndex {\n ... on VenueIndex {\n ...VenueIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\") {\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\") {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n ": types.VenueIndexDocument,
|
||||||
"\n fragment Home on HomePage {\n ... on HomePage {\n featuredEvents {\n id\n }\n }\n }\n": types.HomeFragmentDoc,
|
"\n fragment Home on HomePage {\n ... on HomePage {\n featuredEvents {\n id\n }\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 search($query: String) {\n results: search(query: $query) {\n __typename\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 VenueRentalIndex on VenueRentalIndex {\n ... on VenueRentalIndex {\n title\n lead\n body {\n ...Blocks\n }\n }\n }\n": types.VenueRentalIndexFragmentDoc,
|
"\n fragment VenueRentalIndex on VenueRentalIndex {\n ... on VenueRentalIndex {\n title\n lead\n body {\n ...Blocks\n }\n }\n }\n": types.VenueRentalIndexFragmentDoc,
|
||||||
"\n query venueRentalIndex {\n index: venueRentalIndex {\n ... on VenueRentalIndex {\n ...VenueRentalIndex\n }\n }\n venues: pages(contentType: \"venues.VenuePage\") {\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\") {\n ... on VenuePage {\n ...Venue\n }\n }\n }\n ": types.VenueRentalIndexDocument,
|
||||||
"\n fragment OneLevelOfBlocks 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 ... on HorizontalRuleBlock {\n color\n }\n ... on FeaturedBlock {\n title\n featuredBlockText: text\n linkText\n imagePosition\n backgroundColor\n featuredPage {\n contentType\n pageType\n url\n ... on EventPage {\n featuredImage {\n ...Image\n }\n }\n ... on NewsPage {\n featuredImage {\n ...Image\n }\n }\n }\n featuredImageOverride {\n ...Image\n }\n }\n ... on ContactListBlock {\n items {\n blockType\n ... on ContactEntityBlock {\n contactEntity {\n ...ContactEntity\n }\n }\n }\n }\n ... on EmbedBlock {\n url\n embed\n rawEmbed\n }\n }\n": types.OneLevelOfBlocksFragmentDoc,
|
"\n fragment OneLevelOfBlocks 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 ... on HorizontalRuleBlock {\n color\n }\n ... on FeaturedBlock {\n title\n featuredBlockText: text\n linkText\n imagePosition\n backgroundColor\n featuredPage {\n contentType\n pageType\n url\n ... on EventPage {\n featuredImage {\n ...Image\n }\n }\n ... on NewsPage {\n featuredImage {\n ...Image\n }\n }\n }\n featuredImageOverride {\n ...Image\n }\n }\n ... on ContactListBlock {\n items {\n blockType\n ... on ContactEntityBlock {\n contactEntity {\n ...ContactEntity\n }\n }\n }\n }\n ... on EmbedBlock {\n url\n embed\n rawEmbed\n }\n }\n": types.OneLevelOfBlocksFragmentDoc,
|
||||||
@ -149,6 +150,10 @@ 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.
|
* 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: 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 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 news: pages(contentType: \"news.newsPage\", order: \"-first_published_at\", limit: 4) {\n ... on NewsPage {\n ...News\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 news: pages(contentType: \"news.newsPage\", order: \"-first_published_at\", limit: 4) {\n ... on NewsPage {\n ...News\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 news: pages(contentType: \"news.newsPage\", order: \"-first_published_at\", limit: 4) {\n ... on NewsPage {\n ...News\n }\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 search($query: String) {\n results: search(query: $query) {\n __typename\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 documents)["\n query search($query: String) {\n results: search(query: $query) {\n __typename\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 "];
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
File diff suppressed because one or more lines are too long
@ -27,6 +27,16 @@ export const PIG_NAMES = [
|
|||||||
"peek",
|
"peek",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export function getSearchPath(query: string): string {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
if (query) {
|
||||||
|
params.set("q", query);
|
||||||
|
} else {
|
||||||
|
params.delete("q");
|
||||||
|
}
|
||||||
|
return `/sok?${params.toString()}`;
|
||||||
|
}
|
||||||
|
|
||||||
export function randomElement(array: any[]): any | undefined {
|
export function randomElement(array: any[]): any | undefined {
|
||||||
return array.length
|
return array.length
|
||||||
? array[Math.floor(Math.random() * array.length)]
|
? array[Math.floor(Math.random() * array.length)]
|
||||||
|
Reference in New Issue
Block a user