feat(SW-66, SW-348): search functionality and ui
This commit is contained in:
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user