feat(SW-3108): Added external link option to top primary button on content/collection page

Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-09-15 06:47:10 +00:00
parent ce71fc421c
commit 5654569a11
5 changed files with 56 additions and 26 deletions

View File

@@ -25,6 +25,7 @@
fragment TopPrimaryButton_CollectionPage on CollectionPageHeader {
top_primary_button {
title
is_contentstack_link
linkConnection {
edges {
node {
@@ -43,6 +44,10 @@ fragment TopPrimaryButton_CollectionPage on CollectionPageHeader {
}
}
}
external_link {
href
title
}
}
}

View File

@@ -25,6 +25,7 @@
fragment TopPrimaryButton_ContentPage on ContentPageHeader {
top_primary_button {
title
is_contentstack_link
linkConnection {
edges {
node {
@@ -43,6 +44,10 @@ fragment TopPrimaryButton_ContentPage on ContentPageHeader {
}
}
}
external_link {
href
title
}
}
}

View File

@@ -21,6 +21,7 @@ import {
linkAndTitleSchema,
linkConnectionRefs,
} from "../schemas/linkConnection"
import { internalOrExternalLinkSchema } from "../schemas/pageLinks"
import { systemSchema } from "../schemas/system"
// Block schemas
@@ -73,18 +74,6 @@ const navigationLinksSchema = z
}))
})
const topPrimaryButtonSchema = linkAndTitleSchema
.nullable()
.transform((data) => {
if (!data?.link) {
return null
}
return {
url: data.link.url,
title: data.title || data.link.title || null,
}
})
// Content Page Schema and types
export const collectionPageSchema = z.object({
collection_page: z.object({
@@ -94,7 +83,7 @@ export const collectionPageSchema = z.object({
header: z.object({
heading: z.string(),
preamble: z.string(),
top_primary_button: topPrimaryButtonSchema,
top_primary_button: internalOrExternalLinkSchema,
navigation_links: navigationLinksSchema,
}),
meeting_package: z

View File

@@ -36,6 +36,7 @@ import {
linkAndTitleSchema,
linkConnectionRefs,
} from "../schemas/linkConnection"
import { internalOrExternalLinkSchema } from "../schemas/pageLinks"
import {
contentRefsSchema as sidebarContentRefsSchema,
contentSchema as sidebarContentSchema,
@@ -189,18 +190,6 @@ const navigationLinksSchema = z
}))
})
const topPrimaryButtonSchema = linkAndTitleSchema
.nullable()
.transform((data) => {
if (!data?.link) {
return null
}
return {
url: data.link.url,
title: data.title || data.link.title || null,
}
})
// Content Page Schema and types
export const contentPageSchema = z.object({
content_page: z.object({
@@ -211,7 +200,7 @@ export const contentPageSchema = z.object({
header: z.object({
heading: z.string(),
preamble: z.string(),
top_primary_button: topPrimaryButtonSchema,
top_primary_button: internalOrExternalLinkSchema,
navigation_links: navigationLinksSchema,
dynamic_content: headerDynamicContentSchema.nullish(),
}),

View File

@@ -1,6 +1,7 @@
import { z } from "zod"
import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url"
import { nullableStringValidator } from "@scandic-hotels/common/utils/zod/stringValidator"
import { ContentEnum } from "../../../types/content"
import { systemSchema } from "./system"
@@ -206,6 +207,47 @@ export function transformPageLink(data: Data) {
}
}
export const internalOrExternalLinkSchema = z
.object({
is_contentstack_link: z.boolean().nullish(),
external_link: z
.object({
href: nullableStringValidator,
title: z.string().nullish(),
})
.nullish(),
title: nullableStringValidator,
linkConnection: z.object({
edges: z.array(
z.object({
node: linkUnionSchema.transform((data) => {
const link = transformPageLink(data)
if (link) {
return link
}
return data
}),
})
),
}),
})
.transform(
({ is_contentstack_link, external_link, linkConnection, title }) => {
if (is_contentstack_link !== false && linkConnection.edges.length) {
const linkRef = linkConnection.edges[0].node
return {
title: title || linkRef.title,
url: linkRef.url,
}
} else if (is_contentstack_link === false && external_link?.href) {
return {
title: title || external_link.title || "",
url: external_link.href,
}
}
}
)
export const linkRefsUnionSchema = z.discriminatedUnion("__typename", [
accountPageRefSchema,
campaignOverviewPageRefSchema,