feat(SW-497): Changed to siteConfig which includes Global Alert

This commit is contained in:
Erik Tiekstra
2024-10-03 11:29:26 +02:00
parent 78569fcb21
commit 3f12246e12
6 changed files with 166 additions and 120 deletions

View File

@@ -1,7 +1,7 @@
#import "../Fragments/GlobalAlert.graphql" #import "../Fragments/GlobalAlert.graphql"
query GetSiteConfiguration($locale: String!) { query GetSiteConfig($locale: String!) {
all_site_configuration(limit: 1, locale: $locale) { all_site_config(limit: 1, locale: $locale) {
items { items {
sitewide_alert { sitewide_alert {
booking_widget_disabled booking_widget_disabled

View File

@@ -15,7 +15,7 @@ import { removeMultipleSlashes } from "@/utils/url"
import { systemSchema } from "../schemas/system" import { systemSchema } from "../schemas/system"
import { Image } from "@/types/image" import { Image } from "@/types/image"
import { GlobalAlertType } from "@/types/trpc/routers/contentstack/siteConfiguration" import { GlobalAlertType } from "@/types/trpc/routers/contentstack/siteConfig"
// Help me write this zod schema based on the type ContactConfig // Help me write this zod schema based on the type ContactConfig
export const validateContactConfigSchema = z.object({ export const validateContactConfigSchema = z.object({
@@ -669,15 +669,15 @@ export const globalAlertSchema = z.object({
text: z.string(), text: z.string(),
heading: z.string(), heading: z.string(),
phone_contact: z.object({ phone_contact: z.object({
display_text: z.string(), display_text: z.string().nullable(),
phone_number: z.string(), phone_number: z.string().nullable(),
footnote: z.string(), footnote: z.string().nullable(),
}), }),
}) })
export const siteConfigurationSchema = z export const siteConfigSchema = z
.object({ .object({
all_site_configuration: z.object({ all_site_config: z.object({
items: z items: z
.array( .array(
z.object({ z.object({
@@ -699,14 +699,14 @@ export const siteConfigurationSchema = z
}), }),
}) })
.transform((data) => { .transform((data) => {
if (!data.all_site_configuration.items.length) { if (!data.all_site_config.items.length) {
return { return {
globalAlert: null, globalAlert: null,
bookingWidgetDisabled: false, bookingWidgetDisabled: false,
} }
} }
const { sitewide_alert } = data.all_site_configuration.items[0] const { sitewide_alert } = data.all_site_config.items[0]
return { return {
globalAlert: sitewide_alert.alertConnection.edges[0]?.node || null, globalAlert: sitewide_alert.alertConnection.edges[0]?.node || null,

View File

@@ -1,3 +1,4 @@
import { Lang } from "@/constants/languages"
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql" import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
import { import {
GetCurrentFooter, GetCurrentFooter,
@@ -9,7 +10,7 @@ import {
} from "@/lib/graphql/Query/Current/Header.graphql" } from "@/lib/graphql/Query/Current/Header.graphql"
import { GetFooter, GetFooterRef } from "@/lib/graphql/Query/Footer.graphql" import { GetFooter, GetFooterRef } from "@/lib/graphql/Query/Footer.graphql"
import { GetHeader, GetHeaderRef } from "@/lib/graphql/Query/Header.graphql" import { GetHeader, GetHeaderRef } from "@/lib/graphql/Query/Header.graphql"
import { GetSiteConfiguration } from "@/lib/graphql/Query/SiteConfiguration.graphql" import { GetSiteConfig } from "@/lib/graphql/Query/SiteConfig.graphql"
import { request } from "@/lib/graphql/request" import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc" import { notFound } from "@/server/errors/trpc"
import { contentstackBaseProcedure, router } from "@/server/trpc" import { contentstackBaseProcedure, router } from "@/server/trpc"
@@ -30,7 +31,7 @@ import {
type GetCurrentHeaderData, type GetCurrentHeaderData,
headerRefsSchema, headerRefsSchema,
headerSchema, headerSchema,
siteConfigurationSchema, siteConfigSchema,
validateContactConfigSchema, validateContactConfigSchema,
validateCurrentFooterConfigSchema, validateCurrentFooterConfigSchema,
validateCurrentHeaderConfigSchema, validateCurrentHeaderConfigSchema,
@@ -61,11 +62,15 @@ import {
getHeaderRefsFailCounter, getHeaderRefsFailCounter,
getHeaderRefsSuccessCounter, getHeaderRefsSuccessCounter,
getHeaderSuccessCounter, getHeaderSuccessCounter,
getSiteConfigurationCounter, getSiteConfigCounter,
getSiteConfigurationFailCounter, getSiteConfigFailCounter,
getSiteConfigurationSuccessCounter, getSiteConfigSuccessCounter,
} from "./telemetry" } from "./telemetry"
import { getConnections, getFooterConnections } from "./utils" import {
getConnections,
getFooterConnections,
getGlobalAlertPhoneContactData,
} from "./utils"
import type { import type {
FooterDataRaw, FooterDataRaw,
@@ -75,71 +80,74 @@ import type {
GetHeader as GetHeaderData, GetHeader as GetHeaderData,
GetHeaderRefs, GetHeaderRefs,
} from "@/types/trpc/routers/contentstack/header" } from "@/types/trpc/routers/contentstack/header"
import type { GetSiteConfigurationData } from "@/types/trpc/routers/contentstack/siteConfiguration" import type { GetSiteConfigData } from "@/types/trpc/routers/contentstack/siteConfig"
async function getContactConfig(lang: Lang) {
getContactConfigCounter.add(1, { lang })
console.info(
"contentstack.contactConfig start",
JSON.stringify({ query: { lang } })
)
const response = await request<ContactConfigData>(
GetContactConfig,
{
locale: lang,
},
{
cache: "force-cache",
next: {
tags: [`${lang}:contact`],
},
}
)
if (!response.data) {
const notFoundError = notFound(response)
getContactConfigFailCounter.add(1, {
lang,
error_type: "not_found",
error: JSON.stringify({ code: notFoundError.code }),
})
console.error(
"contentstack.config not found error",
JSON.stringify({ query: { lang }, error: { code: notFoundError.code } })
)
throw notFoundError
}
const validatedContactConfigConfig = validateContactConfigSchema.safeParse(
response.data
)
if (!validatedContactConfigConfig.success) {
getContactConfigFailCounter.add(1, {
lang,
error_type: "validation_error",
error: JSON.stringify(validatedContactConfigConfig.error),
})
console.error(
"contentstack.contactConfig validation error",
JSON.stringify({
query: { lang },
error: validatedContactConfigConfig.error,
})
)
return null
}
getContactConfigSuccessCounter.add(1, { lang })
console.info(
"contentstack.contactConfig success",
JSON.stringify({ query: { lang } })
)
return validatedContactConfigConfig.data.all_contact_config.items[0]
}
export const baseQueryRouter = router({ export const baseQueryRouter = router({
contact: contentstackBaseProcedure.query(async ({ ctx }) => { contact: contentstackBaseProcedure.query(async ({ ctx }) => {
const { lang } = ctx return await getContactConfig(ctx.lang)
getContactConfigCounter.add(1, { lang })
console.info(
"contentstack.contactConfig start",
JSON.stringify({ query: { lang } })
)
const response = await request<ContactConfigData>(
GetContactConfig,
{
locale: lang,
},
{
cache: "force-cache",
next: {
tags: [`${lang}:contact`],
},
}
)
if (!response.data) {
const notFoundError = notFound(response)
getContactConfigFailCounter.add(1, {
lang,
error_type: "not_found",
error: JSON.stringify({ code: notFoundError.code }),
})
console.error(
"contentstack.config not found error",
JSON.stringify({ query: { lang }, error: { code: notFoundError.code } })
)
throw notFoundError
}
const validatedContactConfigConfig = validateContactConfigSchema.safeParse(
response.data
)
if (!validatedContactConfigConfig.success) {
getContactConfigFailCounter.add(1, {
lang,
error_type: "validation_error",
error: JSON.stringify(validatedContactConfigConfig.error),
})
console.error(
"contentstack.contactConfig validation error",
JSON.stringify({
query: { lang },
error: validatedContactConfigConfig.error,
})
)
return null
}
getContactConfigSuccessCounter.add(1, { lang })
console.info(
"contentstack.contactConfig success",
JSON.stringify({ query: { lang } })
)
return validatedContactConfigConfig.data.all_contact_config.items[0]
}), }),
header: contentstackBaseProcedure.query(async ({ ctx }) => { header: contentstackBaseProcedure.query(async ({ ctx }) => {
const { lang } = ctx const { lang } = ctx
@@ -594,67 +602,83 @@ export const baseQueryRouter = router({
return validatedFooterConfig.data return validatedFooterConfig.data
}), }),
siteConfiguration: contentstackBaseProcedure.query(async ({ ctx }) => { siteConfig: contentstackBaseProcedure.query(async ({ ctx }) => {
const { lang } = ctx const { lang } = ctx
getSiteConfigurationCounter.add(1, { lang }) getSiteConfigCounter.add(1, { lang })
console.info( console.info(
"contentstack.siteConfiguration start", "contentstack.siteConfig start",
JSON.stringify({ query: { lang } }) JSON.stringify({ query: { lang } })
) )
const response = await request<GetSiteConfigurationData>( const [siteConfigResponse, contactConfig] = await Promise.all([
GetSiteConfiguration, request<GetSiteConfigData>(
{ GetSiteConfig,
locale: lang, {
}, locale: lang,
{
cache: "force-cache",
next: {
tags: [`${lang}:siteConfiguration`],
}, },
} {
) cache: "force-cache",
next: {
tags: [`${lang}:siteConfig`],
},
}
),
getContactConfig(lang),
])
if (!response.data) { if (!siteConfigResponse.data) {
const notFoundError = notFound(response) const notFoundError = notFound(siteConfigResponse)
getSiteConfigurationFailCounter.add(1, { getSiteConfigFailCounter.add(1, {
lang, lang,
error_type: "not_found", error_type: "not_found",
error: JSON.stringify({ code: notFoundError.code }), error: JSON.stringify({ code: notFoundError.code }),
}) })
console.error( console.error(
"contentstack.siteConfiguration not found error", "contentstack.siteConfig not found error",
JSON.stringify({ query: { lang }, error: { code: notFoundError.code } }) JSON.stringify({ query: { lang }, error: { code: notFoundError.code } })
) )
throw notFoundError throw notFoundError
} }
const validatedSiteConfiguration = siteConfigurationSchema.safeParse( const validatedSiteConfig = siteConfigSchema.safeParse(
response.data siteConfigResponse.data
) )
if (!validatedSiteConfiguration.success) { if (!validatedSiteConfig.success) {
getSiteConfigurationFailCounter.add(1, { getSiteConfigFailCounter.add(1, {
lang, lang,
error_type: "validation_error", error_type: "validation_error",
error: JSON.stringify(validatedSiteConfiguration.error), error: JSON.stringify(validatedSiteConfig.error),
}) })
console.error( console.error(
"contentstack.siteConfiguration validation error", "contentstack.siteConfig validation error",
JSON.stringify({ JSON.stringify({
query: { lang }, query: { lang },
error: validatedSiteConfiguration.error, error: validatedSiteConfig.error,
}) })
) )
return null return null
} }
getSiteConfigurationSuccessCounter.add(1, { lang }) getSiteConfigSuccessCounter.add(1, { lang })
console.info( console.info(
"contentstack.siteConfiguration success", "contentstack.siteConfig success",
JSON.stringify({ query: { lang } }) JSON.stringify({ query: { lang } })
) )
return validatedSiteConfiguration.data
const { globalAlert } = validatedSiteConfig.data
return {
...validatedSiteConfig.data,
globalAlert: globalAlert
? {
...globalAlert,
phone_contact: contactConfig
? getGlobalAlertPhoneContactData(globalAlert, contactConfig)
: null,
}
: null,
}
}), }),
}) })

View File

@@ -91,13 +91,13 @@ export const getFooterFailCounter = meter.createCounter(
"trpc.contentstack.footer.get-fail" "trpc.contentstack.footer.get-fail"
) )
// OpenTelemetry metrics: SiteConfiguration // OpenTelemetry metrics: SiteConfig
export const getSiteConfigurationCounter = meter.createCounter( export const getSiteConfigCounter = meter.createCounter(
"trpc.contentstack.SiteConfiguration.get" "trpc.contentstack.SiteConfig.get"
) )
export const getSiteConfigurationSuccessCounter = meter.createCounter( export const getSiteConfigSuccessCounter = meter.createCounter(
"trpc.contentstack.SiteConfiguration.get-success" "trpc.contentstack.SiteConfig.get-success"
) )
export const getSiteConfigurationFailCounter = meter.createCounter( export const getSiteConfigFailCounter = meter.createCounter(
"trpc.contentstack.SiteConfiguration.get-fail" "trpc.contentstack.SiteConfig.get-fail"
) )

View File

@@ -1,11 +1,13 @@
import type { import { getValueFromContactConfig } from "@/utils/contactConfig"
FooterLinkItem,
FooterRefDataRaw, import { ContactConfig } from "./output"
} from "@/types/components/footer/footer"
import type { FooterRefDataRaw } from "@/types/components/footer/footer"
import { System } from "@/types/requests/system" import { System } from "@/types/requests/system"
import { Edges } from "@/types/requests/utils/edges" import { Edges } from "@/types/requests/utils/edges"
import { NodeRefs } from "@/types/requests/utils/refs" import { NodeRefs } from "@/types/requests/utils/refs"
import type { HeaderRefs } from "@/types/trpc/routers/contentstack/header" import type { HeaderRefs } from "@/types/trpc/routers/contentstack/header"
import { SiteConfig } from "@/types/trpc/routers/contentstack/siteConfig"
export function getConnections({ header }: HeaderRefs) { export function getConnections({ header }: HeaderRefs) {
const connections: System["system"][] = [header.system] const connections: System["system"][] = [header.system]
@@ -68,3 +70,23 @@ export function getFooterConnections(refs: FooterRefDataRaw) {
return connections return connections
} }
export function getGlobalAlertPhoneContactData(
globalAlert: SiteConfig["globalAlert"],
contactConfig: ContactConfig
) {
if (globalAlert?.phone_contact) {
const { display_text, phone_number, footnote } = globalAlert.phone_contact
return {
display_text,
phone: phone_number
? getValueFromContactConfig(phone_number, contactConfig)
: null,
footnote: footnote
? getValueFromContactConfig(footnote, contactConfig)
: null,
}
}
return null
}

View File

@@ -2,7 +2,7 @@ import { z } from "zod"
import { import {
globalAlertSchema, globalAlertSchema,
siteConfigurationSchema, siteConfigSchema,
} from "@/server/routers/contentstack/base/output" } from "@/server/routers/contentstack/base/output"
export enum GlobalAlertType { export enum GlobalAlertType {
@@ -10,8 +10,8 @@ export enum GlobalAlertType {
Alarm = "alarm", Alarm = "alarm",
} }
export type GetSiteConfigurationData = z.input<typeof siteConfigurationSchema> export type GetSiteConfigData = z.input<typeof siteConfigSchema>
export type SiteConfiguration = z.output<typeof siteConfigurationSchema> export type SiteConfig = z.output<typeof siteConfigSchema>
export type GetGlobalAlertData = z.input<typeof globalAlertSchema> export type GetGlobalAlertData = z.input<typeof globalAlertSchema>
export type GlobalAlert = z.output<typeof globalAlertSchema> export type GlobalAlert = z.output<typeof globalAlertSchema>