feat/SW-3108 external links

* feat(SW-3108): Added external link options to shortcuts
* feat(SW-3108): Added external link options to header

Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-08-28 07:25:17 +00:00
parent 1a10afdbad
commit fd48f86c90
8 changed files with 213 additions and 98 deletions

View File

@@ -7,6 +7,10 @@ import {
import { Lang } from "@scandic-hotels/common/constants/language"
import { logger } from "@scandic-hotels/common/logger"
import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url"
import {
nullableStringUrlValidator,
nullableStringValidator,
} from "@scandic-hotels/common/utils/zod/stringValidator"
import { discriminatedUnion } from "../../../utils/discriminatedUnion"
import {
@@ -97,7 +101,7 @@ export const validateCurrentHeaderConfigSchema = z
edges: z.array(
z.object({
node: z.object({
description: z.string().optional().nullable(),
description: z.string().nullish(),
dimension: z.object({
height: z.number(),
width: z.number(),
@@ -106,8 +110,8 @@ export const validateCurrentHeaderConfigSchema = z
system: z.object({
uid: z.string(),
}),
title: z.string().optional().default(""),
url: z.string().optional().default(""),
title: nullableStringValidator,
url: nullableStringUrlValidator,
}),
})
),
@@ -178,7 +182,7 @@ const validateAppDownload = z.object({
edges: z.array(
z.object({
node: z.object({
description: z.string().optional().nullable(),
description: z.string().nullish(),
dimension: z.object({
height: z.number(),
width: z.number(),
@@ -220,7 +224,7 @@ export const validateCurrentFooterConfigSchema = z.object({
edges: z.array(
z.object({
node: z.object({
description: z.string().optional().nullable(),
description: z.string().nullish(),
dimension: z.object({
height: z.number(),
width: z.number(),
@@ -248,7 +252,7 @@ export const validateCurrentFooterConfigSchema = z.object({
edges: z.array(
z.object({
node: z.object({
description: z.string().optional().nullable(),
description: z.string().nullish(),
dimension: z.object({
height: z.number(),
width: z.number(),
@@ -561,6 +565,51 @@ export const headerRefsSchema = z
}
})
const internalOrExternalLinkSchema = z
.object({
is_contentstack_link: z.boolean().nullish(),
external_link: z
.object({
href: nullableStringUrlValidator,
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,
}
} else {
return {
title,
}
}
}
)
const linkSchema = z
.object({
linkConnection: z.object({
@@ -590,7 +639,7 @@ const linkSchema = z
})
const titleSchema = z.object({
title: z.string().optional().default(""),
title: nullableStringValidator,
})
/**
@@ -605,7 +654,7 @@ const linkAndTitleSchema = z.intersection(linkSchema, titleSchema)
*/
export const menuItemSchema = z
.intersection(
linkAndTitleSchema,
internalOrExternalLinkSchema,
z
.object({
cardConnection: z.object({
@@ -615,11 +664,11 @@ export const menuItemSchema = z
})
),
}),
see_all_link: linkAndTitleSchema,
see_all_link: internalOrExternalLinkSchema,
submenu: z.array(
z.object({
links: z.array(linkAndTitleSchema),
title: z.string().optional().default(""),
links: z.array(internalOrExternalLinkSchema),
title: nullableStringValidator,
})
),
})
@@ -636,11 +685,13 @@ export const menuItemSchema = z
}
})
)
.transform((data) => {
.transform(({ title, url, card, seeAllLink, submenu }) => {
return {
...data,
link: data.submenu.length ? null : data.link,
seeAllLink: data.submenu.length ? data.seeAllLink : null,
title,
link: submenu.length ? null : { url },
seeAllLink: submenu.length ? seeAllLink : null,
card,
submenu,
}
})
@@ -652,7 +703,7 @@ enum IconName {
}
const topLinkItemSchema = z.intersection(
linkAndTitleSchema,
internalOrExternalLinkSchema,
z.object({
icon: z
.enum(["loyalty", "info", "offer"])