feat(SW-66, SW-348): search functionality and ui

This commit is contained in:
Simon Emanuelsson
2024-08-28 10:47:57 +02:00
parent b9dbcf7d90
commit af850c90e7
437 changed files with 7663 additions and 9881 deletions
@@ -1,20 +1,20 @@
import { metrics } from "@opentelemetry/api"
import { Lang } from "@/constants/languages"
import { GetContentPageRefs } from "@/lib/graphql/Query/ContentPage.graphql"
import { GetContentPageRefs } from "@/lib/graphql/Query/ContentPage/ContentPage.graphql"
import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc"
import { generateTag, generateTags } from "@/utils/generateTag"
import { removeMultipleSlashes } from "@/utils/url"
import { generateTag, generateTagsFromSystem } from "@/utils/generateTag"
import { removeEmptyObjects } from "../../utils"
import { validateContentPageRefsSchema } from "./output"
import { contentPageRefsSchema } from "./output"
import { ContentBlocksTypenameEnum } from "@/types/components/content/enums"
import { Edges } from "@/types/requests/utils/edges"
import { NodeRefs } from "@/types/requests/utils/refs"
import { ContentPageRefsDataRaw } from "@/types/trpc/routers/contentstack/contentPage"
import { ContentPageEnum } from "@/types/enums/contentPage"
import { System } from "@/types/requests/system"
import {
ContentPageRefs,
GetContentPageRefsSchema,
} from "@/types/trpc/routers/contentstack/contentPage"
const meter = metrics.getMeter("trpc.contentPage")
// OpenTelemetry metrics: ContentPage
@@ -41,10 +41,15 @@ export async function fetchContentPageRefs(lang: Lang, uid: string) {
query: { lang, uid },
})
)
const refsResponse = await request<ContentPageRefsDataRaw>(
const refsResponse = await request<GetContentPageRefsSchema>(
GetContentPageRefs,
{ locale: lang, uid },
{ cache: "force-cache", next: { tags: [generateTag(lang, uid)] } }
{
cache: "force-cache",
next: {
tags: [generateTag(lang, uid)],
},
}
)
if (!refsResponse.data) {
const notFoundError = notFound(refsResponse)
@@ -69,11 +74,15 @@ export async function fetchContentPageRefs(lang: Lang, uid: string) {
throw notFoundError
}
return removeEmptyObjects(refsResponse.data)
return refsResponse.data
}
export function validateContentPageRefs(data: any, lang: Lang, uid: string) {
const validatedData = validateContentPageRefsSchema.safeParse(data)
export function validateContentPageRefs(
data: GetContentPageRefsSchema,
lang: Lang,
uid: string
) {
const validatedData = contentPageRefsSchema.safeParse(data)
if (!validatedData.success) {
getContentPageRefsFailCounter.add(1, {
lang,
@@ -97,64 +106,70 @@ export function validateContentPageRefs(data: any, lang: Lang, uid: string) {
query: { lang, uid },
})
)
return validatedData.data
}
export function generatePageTags(validatedData: any, lang: Lang): string[] {
export function generatePageTags(
validatedData: ContentPageRefs,
lang: Lang
): string[] {
const connections = getConnections(validatedData)
return [
generateTags(lang, connections),
generateTagsFromSystem(lang, connections),
generateTag(lang, validatedData.content_page.system.uid),
].flat()
}
export function getConnections(refs: ContentPageRefsDataRaw) {
const connections: Edges<NodeRefs>[] = []
if (refs.content_page.blocks) {
refs.content_page.blocks.forEach((item) => {
switch (item.__typename) {
case ContentBlocksTypenameEnum.ContentPageBlocksContent: {
if (item.content.content.embedded_itemsConnection.edges.length) {
connections.push(item.content.content.embedded_itemsConnection)
export function getConnections({ content_page }: ContentPageRefs) {
const connections: System["system"][] = [content_page.system]
if (content_page.blocks) {
content_page.blocks.forEach((block) => {
switch (block.__typename) {
case ContentPageEnum.ContentStack.blocks.Content:
{
if (block.content.length) {
// TS has trouble infering the filtered types
// @ts-ignore
connections.push(...block.content)
}
}
break
case ContentPageEnum.ContentStack.blocks.Shortcuts: {
if (block.shortcuts.shortcuts.length) {
connections.push(...block.shortcuts.shortcuts)
}
break
}
case ContentBlocksTypenameEnum.ContentPageBlocksShortcuts: {
item.shortcuts.shortcuts.forEach((shortcut) => {
if (shortcut.linkConnection.edges.length) {
connections.push(shortcut.linkConnection)
}
})
case ContentPageEnum.ContentStack.blocks.TextCols: {
if (block.text_cols.length) {
connections.push(...block.text_cols)
}
break
}
}
})
}
if (content_page.sidebar) {
content_page.sidebar.forEach((block) => {
switch (block.__typename) {
case ContentPageEnum.ContentStack.sidebar.Content:
if (block.content.length) {
connections.push(...block.content)
}
break
case ContentPageEnum.ContentStack.sidebar.JoinLoyaltyContact:
if (block.join_loyalty_contact?.button) {
connections.push(block.join_loyalty_contact.button)
}
break
default:
break
}
})
}
return connections
}
export function makeButtonObject(button: any) {
if (!button) return null
const isContenstackLink =
button?.is_contentstack_link || button.linkConnection?.edges?.length
const linkConnnectionNode = isContenstackLink
? button.linkConnection.edges[0]?.node
: null
return {
openInNewTab: button?.open_in_new_tab,
title:
button.cta_text ||
(linkConnnectionNode
? linkConnnectionNode.title
: button.external_link.title),
href: linkConnnectionNode
? linkConnnectionNode.web?.original_url ||
removeMultipleSlashes(
`/${linkConnnectionNode.system.locale}/${linkConnnectionNode.url}`
)
: button.external_link.href,
isExternal: !isContenstackLink,
}
}