fix: resolve selected winners from populated CMS data
This commit is contained in:
@@ -42,6 +42,14 @@ export function useCmsCollection(collection: CmsRouteCollection) {
|
||||
return useCmsRoute()?.lists?.[collection] || []
|
||||
}
|
||||
|
||||
export function resolveCmsRelationship(entry: unknown, docs: CmsRouteDoc[]) {
|
||||
const entryID = entry && typeof entry === 'object' ? (entry as { id?: unknown }).id : entry
|
||||
const populatedDoc = docs.find((doc) => String(doc.id) === String(entryID))
|
||||
|
||||
if (populatedDoc) return populatedDoc
|
||||
return entry && typeof entry === 'object' ? (entry as CmsRouteDoc) : undefined
|
||||
}
|
||||
|
||||
export function useApplicationPhase() {
|
||||
return useCmsRoute()?.applicationPhase
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import TestimonialsSection from '@/spa/components/TestimonialsSection'
|
||||
import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg'
|
||||
import Image from '@/spa/components/ui/UnoptimizedImage'
|
||||
import { mediaAlt, mediaUrl } from '@/spa/cmsMediaField'
|
||||
import { useCmsCollection, useCmsRoute, type CmsRouteDoc } from '@/spa/cmsRoute'
|
||||
import { resolveCmsRelationship, useCmsCollection, useCmsRoute, type CmsRouteDoc } from '@/spa/cmsRoute'
|
||||
import { WINNERS, type Winner } from '@/spa/data/winners'
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile'
|
||||
import { Link } from '@/spa/router'
|
||||
@@ -108,17 +108,6 @@ const normalizeWinner = (
|
||||
}
|
||||
}
|
||||
|
||||
const winnerFromRelationship = (
|
||||
entry: unknown,
|
||||
allDocs: CmsRouteDoc[],
|
||||
placeholderImage: string,
|
||||
fallbackWinner: typeof aboutContent.highlights.fallbackWinner,
|
||||
) => {
|
||||
if (entry && typeof entry === 'object') return normalizeWinner(entry as CmsRouteDoc, placeholderImage, fallbackWinner)
|
||||
const doc = allDocs.find((item) => String(item.id) === String(entry))
|
||||
return normalizeWinner(doc, placeholderImage, fallbackWinner)
|
||||
}
|
||||
|
||||
const About: React.FC = () => {
|
||||
const isMobile = useIsMobile()
|
||||
const placeholderImage = usePreistraegerPlaceholderImage()
|
||||
@@ -144,7 +133,7 @@ const About: React.FC = () => {
|
||||
|
||||
const highlightWinners = useMemo(() => {
|
||||
const selected = fallbackArray<unknown>(highlights.selectedWinners, [])
|
||||
.map((entry) => winnerFromRelationship(entry, cmsWinners, placeholderImage, highlightFallbackWinner))
|
||||
.map((entry) => normalizeWinner(resolveCmsRelationship(entry, cmsWinners), placeholderImage, highlightFallbackWinner))
|
||||
.filter((winner): winner is Winner => Boolean(winner))
|
||||
|
||||
if (selected.length) return selected.slice(0, 8)
|
||||
|
||||
@@ -11,7 +11,7 @@ import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
import Image from '@/spa/components/ui/UnoptimizedImage'
|
||||
import type { SpaApplicationPhaseData, SpaApplicationPhaseItem } from '@/spa/applicationPhase'
|
||||
import { useApplicationPhase, useCmsCollection, useCmsRoute } from '@/spa/cmsRoute'
|
||||
import { resolveCmsRelationship, useApplicationPhase, useCmsCollection, useCmsRoute } from '@/spa/cmsRoute'
|
||||
import { mediaAlt, mediaUrl } from '@/spa/cmsMediaField'
|
||||
import { homeContent } from '@/spa/homeContent'
|
||||
import { netzwerkContent } from '@/spa/netzwerkContent'
|
||||
@@ -276,13 +276,8 @@ const Home: React.FC = () => {
|
||||
};
|
||||
const showHeroSecondaryCta = !HIDE_MEMBERSHIP_HOME_HERO_CTA || !isMembershipCta(heroSecondaryCta);
|
||||
const selectedWinnerDocs = selectedWinners
|
||||
.map((selected) => {
|
||||
const selectedRecord = selected as { id?: string | number }
|
||||
const selectedID = typeof selected === 'object' && selected !== null ? selectedRecord.id : selected
|
||||
const listDoc = cmsPreistraeger.find((doc) => String((doc as { id?: string | number }).id) === String(selectedID))
|
||||
return listDoc || (typeof selected === 'object' ? selected : undefined)
|
||||
})
|
||||
.filter(Boolean)
|
||||
.map((selected) => resolveCmsRelationship(selected, cmsPreistraeger))
|
||||
.filter(Boolean)
|
||||
const homeWinners = selectedWinnerDocs.length
|
||||
? selectedWinnerDocs
|
||||
: (cmsPreistraeger.length ? cmsPreistraeger : WINNERS).filter((w) => Number((w as { year?: string | number }).year) === 2025).slice(0, 8);
|
||||
|
||||
25
tests/int/cms-route-relationship.int.spec.ts
Normal file
25
tests/int/cms-route-relationship.int.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { resolveCmsRelationship, type CmsRouteDoc } from '@/spa/cmsRoute'
|
||||
|
||||
const fullWinner: CmsRouteDoc = {
|
||||
id: 20,
|
||||
title: 'Adelholzener Alpenquellen GmbH',
|
||||
image: { id: 55, url: '/api/media/file/image%20(1).png' },
|
||||
}
|
||||
|
||||
describe('CMS relationship resolution', () => {
|
||||
it('prefers the fully populated collection document over a shallow relationship object', () => {
|
||||
expect(resolveCmsRelationship({ id: 20, image: 55 }, [fullWinner])).toBe(fullWinner)
|
||||
})
|
||||
|
||||
it('resolves an ID-only relationship', () => {
|
||||
expect(resolveCmsRelationship(20, [fullWinner])).toBe(fullWinner)
|
||||
})
|
||||
|
||||
it('preserves a populated relationship when no list document is available', () => {
|
||||
const relationship = { id: 20, image: { id: 55, url: '/api/media/file/image%20(1).png' } }
|
||||
|
||||
expect(resolveCmsRelationship(relationship, [])).toBe(relationship)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user