From e65be3f47831c35ecedaea0e4d72d4a8ec9677b0 Mon Sep 17 00:00:00 2001 From: runarvestmann Date: Fri, 29 Nov 2024 10:50:29 +0000 Subject: [PATCH 1/8] Fix level 1 sitemap links --- libs/cms/src/lib/cms.contentful.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/cms/src/lib/cms.contentful.service.ts b/libs/cms/src/lib/cms.contentful.service.ts index fe3c3065a7a3..4ce8458dcf95 100644 --- a/libs/cms/src/lib/cms.contentful.service.ts +++ b/libs/cms/src/lib/cms.contentful.service.ts @@ -1219,7 +1219,7 @@ export class CmsContentfulService { label: node.label, href: `/${getOrganizationPageUrlPrefix(input.lang)}/${ input.organizationPageSlug - }/${node.slug}`, + }/${input.categorySlug}/${node.slug}`, description: node.description, } } @@ -1270,7 +1270,7 @@ export class CmsContentfulService { node.label = parentSubpage.fields.title node.href = `/${getOrganizationPageUrlPrefix(input.lang)}/${ input.organizationPageSlug - }/${parentSubpage.fields.slug}` + }/${input.categorySlug}/${parentSubpage.fields.slug}` } } From 3e941df60e85371f3ba9946daae002b89b9d6282 Mon Sep 17 00:00:00 2001 From: runarvestmann Date: Fri, 29 Nov 2024 10:51:22 +0000 Subject: [PATCH 2/8] Update sitemap level 1 entry node links --- libs/cms/src/lib/cms.contentful.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/cms/src/lib/cms.contentful.service.ts b/libs/cms/src/lib/cms.contentful.service.ts index 4ce8458dcf95..8cc1368eeb7c 100644 --- a/libs/cms/src/lib/cms.contentful.service.ts +++ b/libs/cms/src/lib/cms.contentful.service.ts @@ -1270,7 +1270,7 @@ export class CmsContentfulService { node.label = parentSubpage.fields.title node.href = `/${getOrganizationPageUrlPrefix(input.lang)}/${ input.organizationPageSlug - }/${input.categorySlug}/${parentSubpage.fields.slug}` + }/${parentSubpage.fields.slug}` } } From 973f75e68b436580c80e37980a398561e3c55994 Mon Sep 17 00:00:00 2001 From: runarvestmann Date: Fri, 29 Nov 2024 12:59:36 +0000 Subject: [PATCH 3/8] Make sure that subpages belong to same main page --- libs/cms/src/lib/generated/contentfulTypes.d.ts | 3 +++ libs/cms/src/lib/models/organizationParentSubpage.model.ts | 2 ++ 2 files changed, 5 insertions(+) diff --git a/libs/cms/src/lib/generated/contentfulTypes.d.ts b/libs/cms/src/lib/generated/contentfulTypes.d.ts index dee46c12b306..aa7d3875ab85 100644 --- a/libs/cms/src/lib/generated/contentfulTypes.d.ts +++ b/libs/cms/src/lib/generated/contentfulTypes.d.ts @@ -3241,6 +3241,9 @@ export interface IOrganizationPage extends Entry { } export interface IOrganizationParentSubpageFields { + /** Organization Page */ + organizationPage: IOrganizationPage + /** Internal Title */ internalTitle: string diff --git a/libs/cms/src/lib/models/organizationParentSubpage.model.ts b/libs/cms/src/lib/models/organizationParentSubpage.model.ts index 9c9a4d927059..a320aff2075a 100644 --- a/libs/cms/src/lib/models/organizationParentSubpage.model.ts +++ b/libs/cms/src/lib/models/organizationParentSubpage.model.ts @@ -35,6 +35,8 @@ export const mapOrganizationParentSubpage = ({ fields.pages ?.filter( (page) => + page.fields.organizationPage?.sys?.id === + fields.organizationPage?.sys?.id && Boolean(page.fields.organizationPage?.fields?.slug) && Boolean(page.fields.slug), ) From 1b1490101250a4e0ac2934a4dd882710fddb7c95 Mon Sep 17 00:00:00 2001 From: runarvestmann Date: Mon, 2 Dec 2024 14:39:03 +0000 Subject: [PATCH 4/8] Fetch level 2 sitemap and display on a page --- apps/web/pages/s/[...slugs]/index.tsx | 31 +++ .../Organization/Standalone/Level2Sitemap.tsx | 185 ++++++++++++++++++ apps/web/screens/queries/Organization.tsx | 18 ++ libs/cms/src/lib/cms.contentful.service.ts | 163 ++++++++++++++- libs/cms/src/lib/cms.resolver.ts | 20 +- ...OrganizationPageStandaloneSitemap.input.ts | 7 + ...organizationPageStandaloneSitemap.model.ts | 30 +++ 7 files changed, 445 insertions(+), 9 deletions(-) create mode 100644 apps/web/screens/Organization/Standalone/Level2Sitemap.tsx diff --git a/apps/web/pages/s/[...slugs]/index.tsx b/apps/web/pages/s/[...slugs]/index.tsx index 8060f8453d5e..ef0d7dc2420b 100644 --- a/apps/web/pages/s/[...slugs]/index.tsx +++ b/apps/web/pages/s/[...slugs]/index.tsx @@ -34,6 +34,9 @@ import StandaloneHome, { import StandaloneLevel1Sitemap, { type StandaloneLevel1SitemapProps, } from '@island.is/web/screens/Organization/Standalone/Level1Sitemap' +import StandaloneLevel2Sitemap, { + type StandaloneLevel2SitemapProps, +} from '@island.is/web/screens/Organization/Standalone/Level2Sitemap' import StandaloneParentSubpage, { StandaloneParentSubpageProps, } from '@island.is/web/screens/Organization/Standalone/ParentSubpage' @@ -50,6 +53,7 @@ enum PageType { STANDALONE_FRONTPAGE = 'standalone-frontpage', STANDALONE_PARENT_SUBPAGE = 'standalone-parent-subpage', STANDALONE_LEVEL1_SITEMAP = 'standalone-level1-sitemap', + STANDALONE_LEVEL2_SITEMAP = 'standalone-level2-sitemap', SUBPAGE = 'subpage', ALL_NEWS = 'news', PUBLISHED_MATERIAL = 'published-material', @@ -69,6 +73,9 @@ const pageMap: Record> = { [PageType.STANDALONE_LEVEL1_SITEMAP]: (props) => ( ), + [PageType.STANDALONE_LEVEL2_SITEMAP]: (props) => ( + + ), [PageType.SUBPAGE]: (props) => , [PageType.ALL_NEWS]: (props) => , [PageType.PUBLISHED_MATERIAL]: (props) => , @@ -101,6 +108,10 @@ interface Props { type: PageType.STANDALONE_LEVEL1_SITEMAP props: StandaloneLevel1SitemapProps } + | { + type: PageType.STANDALONE_LEVEL2_SITEMAP + props: StandaloneLevel2SitemapProps + } | { type: PageType.SUBPAGE props: { @@ -316,6 +327,26 @@ Component.getProps = async (context) => { } } + if ( + isStandaloneTheme && + organizationPage.topLevelNavigation?.links.some( + (link) => slugs[1] === link.href.split('/').pop(), + ) + ) { + try { + return { + page: { + type: PageType.STANDALONE_LEVEL2_SITEMAP, + props: await StandaloneLevel2Sitemap.getProps(modifiedContext), + }, + } + } catch (error) { + if (!(error instanceof CustomNextError)) { + throw error + } + } + } + if (isStandaloneTheme) { return { page: { diff --git a/apps/web/screens/Organization/Standalone/Level2Sitemap.tsx b/apps/web/screens/Organization/Standalone/Level2Sitemap.tsx new file mode 100644 index 000000000000..dc5713d7ea37 --- /dev/null +++ b/apps/web/screens/Organization/Standalone/Level2Sitemap.tsx @@ -0,0 +1,185 @@ +import { useMemo } from 'react' + +import { + BreadCrumbItem, + Breadcrumbs, + GridColumn, + GridContainer, + GridRow, + LinkV2, + Stack, +} from '@island.is/island-ui/core' +import { Text } from '@island.is/island-ui/core' +import { + ContentLanguage, + OrganizationPage, + OrganizationPageStandaloneSitemapLevel2, + OrganizationPageTopLevelNavigationLink, + Query, + QueryGetOrganizationPageArgs, + QueryGetOrganizationPageStandaloneSitemapLevel2Args, +} from '@island.is/web/graphql/schema' +import { useLinkResolver } from '@island.is/web/hooks' +import useContentfulId from '@island.is/web/hooks/useContentfulId' +import { StandaloneLayout } from '@island.is/web/layouts/organization/standalone' +import type { Screen, ScreenContext } from '@island.is/web/types' +import { CustomNextError } from '@island.is/web/units/errors' + +import { + GET_ORGANIZATION_PAGE_QUERY, + GET_ORGANIZATION_PAGE_STANDALONE_SITEMAP_LEVEL2_QUERY, +} from '../../queries' + +const LanguageToggleSetup = (props: { ids: string[] }) => { + useContentfulId(...props.ids) + return null +} + +type StandaloneLevel2SitemapScreenContext = ScreenContext & { + organizationPage?: Query['getOrganizationPage'] +} + +export interface StandaloneLevel2SitemapProps { + organizationPage: OrganizationPage + category?: OrganizationPageTopLevelNavigationLink + sitemap: OrganizationPageStandaloneSitemapLevel2 +} + +const StandaloneLevel2Sitemap: Screen< + StandaloneLevel2SitemapProps, + StandaloneLevel2SitemapScreenContext +> = ({ organizationPage, category, sitemap }) => { + const { linkResolver } = useLinkResolver() + + const breadcrumbItems: BreadCrumbItem[] = useMemo(() => { + const items: BreadCrumbItem[] = [ + { + title: organizationPage.title, + href: linkResolver('organizationpage', [organizationPage.slug]).href, + }, + ] + + if (category) { + items.push({ + title: category.label, + href: category.href, + }) + } + return items + }, [category, linkResolver, organizationPage.slug, organizationPage.title]) + + return ( + + + + + + + + + + {sitemap.label} + + + {sitemap.childCategories.map(({ label, childLinks }) => ( + + + {label} + + + {childLinks.map((link) => ( + + {link.label} + + ))} + + + ))} + + + + + + + + ) +} + +StandaloneLevel2Sitemap.getProps = async ({ + apolloClient, + locale, + query, + organizationPage, +}) => { + const [organizationPageSlug, categorySlug, subcategorySlug] = (query.slugs ?? + []) as string[] + + const [ + { + data: { getOrganizationPage }, + }, + { + data: { getOrganizationPageStandaloneSitemapLevel2 }, + }, + ] = await Promise.all([ + !organizationPage + ? apolloClient.query({ + query: GET_ORGANIZATION_PAGE_QUERY, + variables: { + input: { + slug: organizationPageSlug, + lang: locale as ContentLanguage, + }, + }, + }) + : { + data: { getOrganizationPage: organizationPage }, + }, + apolloClient.query< + Query, + QueryGetOrganizationPageStandaloneSitemapLevel2Args + >({ + query: GET_ORGANIZATION_PAGE_STANDALONE_SITEMAP_LEVEL2_QUERY, + variables: { + input: { + organizationPageSlug, + categorySlug, + subcategorySlug, + lang: locale as ContentLanguage, + }, + }, + }), + ]) + + if (!getOrganizationPage) { + throw new CustomNextError(404, 'Organization page was not found') + } + + if (!getOrganizationPageStandaloneSitemapLevel2) { + throw new CustomNextError( + 404, + 'Organization page standalone level 2 sitemap was not found', + ) + } + + const category = organizationPage?.topLevelNavigation?.links.find( + (link) => categorySlug === link.href.split('/').pop(), + ) + + return { + organizationPage: getOrganizationPage, + category, + sitemap: getOrganizationPageStandaloneSitemapLevel2, + } +} + +export default StandaloneLevel2Sitemap diff --git a/apps/web/screens/queries/Organization.tsx b/apps/web/screens/queries/Organization.tsx index 5b18fbad140a..8a1c92b5a600 100644 --- a/apps/web/screens/queries/Organization.tsx +++ b/apps/web/screens/queries/Organization.tsx @@ -445,3 +445,21 @@ export const GET_ORGANIZATION_PAGE_STANDALONE_SITEMAP_LEVEL1_QUERY = gql` } } ` + +export const GET_ORGANIZATION_PAGE_STANDALONE_SITEMAP_LEVEL2_QUERY = gql` + query GetOrganizationPageStandaloneSitemapLevel2Query( + $input: GetOrganizationPageStandaloneSitemapLevel2Input! + ) { + getOrganizationPageStandaloneSitemapLevel2(input: $input) { + label + childCategories { + label + href + childLinks { + label + href + } + } + } + } +` diff --git a/libs/cms/src/lib/cms.contentful.service.ts b/libs/cms/src/lib/cms.contentful.service.ts index 8cc1368eeb7c..d6c05a8cf2e0 100644 --- a/libs/cms/src/lib/cms.contentful.service.ts +++ b/libs/cms/src/lib/cms.contentful.service.ts @@ -88,8 +88,14 @@ import { mapServiceWebPage } from './models/serviceWebPage.model' import { mapEvent } from './models/event.model' import { GetOrganizationParentSubpageInput } from './dto/getOrganizationParentSubpage.input' import { mapOrganizationParentSubpage } from './models/organizationParentSubpage.model' -import { GetOrganizationPageStandaloneSitemapLevel1Input } from './dto/getOrganizationPageStandaloneSitemap.input' -import { OrganizationPageStandaloneSitemap } from './models/organizationPageStandaloneSitemap.model' +import { + GetOrganizationPageStandaloneSitemapLevel1Input, + GetOrganizationPageStandaloneSitemapLevel2Input, +} from './dto/getOrganizationPageStandaloneSitemap.input' +import { + OrganizationPageStandaloneSitemap, + OrganizationPageStandaloneSitemapLevel2, +} from './models/organizationPageStandaloneSitemap.model' import { SitemapTree, SitemapTreeNodeType } from '@island.is/shared/types' import { getOrganizationPageUrlPrefix } from '@island.is/shared/utils' @@ -1254,8 +1260,6 @@ export class CmsContentfulService { 1, ) - const entryIdsToRemove: string[] = [] - for (const parentSubpage of parentSubpageResponse.items) { const nodeList = entryNodes.get(parentSubpage.sys.id) if ( @@ -1263,7 +1267,6 @@ export class CmsContentfulService { !parentSubpage.fields.slug || !parentSubpage.fields.title ) { - entryIdsToRemove.push(parentSubpage.sys.id) continue } for (const node of nodeList) { @@ -1274,11 +1277,157 @@ export class CmsContentfulService { } } - // Remove entries from result that could not be resolved to their label or href + // Prune empty values result.childLinks = result.childLinks.filter( - (link) => !('entryId' in link && entryIdsToRemove.includes(link.entryId)), + (link) => link.label && link.href, + ) + + return result + } + + async getOrganizationPageStandaloneSitemapLevel2( + input: GetOrganizationPageStandaloneSitemapLevel2Input, + ): Promise { + const params = { + content_type: 'organizationPage', + 'fields.slug': input.organizationPageSlug, + select: 'fields.sitemap', + limit: 1, + } + + const response = await this.contentfulRepository + .getLocalizedEntries(input.lang, params) + .catch(errorHandler('getOrganizationPageStandaloneSitemapLevel1')) + + const tree = response.items?.[0]?.fields.sitemap?.fields.tree as SitemapTree + + if (!tree) { + return null + } + + const category = tree.childNodes.find( + (node) => + node.type === SitemapTreeNodeType.CATEGORY && + node.slug === input.categorySlug, ) + if (!category) { + return null + } + + const subcategory = category.childNodes.find( + (node) => + node.type === SitemapTreeNodeType.CATEGORY && + node.slug === input.subcategorySlug, + ) + + if (!subcategory || subcategory.type !== SitemapTreeNodeType.CATEGORY) { + return null + } + + const entryNodes = new Map< + string, + { label: string; href: string; entryId: string }[] + >() + + const result: OrganizationPageStandaloneSitemapLevel2 = { + label: subcategory.label, + childCategories: subcategory.childNodes.map((node) => { + if (node.type === SitemapTreeNodeType.CATEGORY) { + return { + label: node.label, + childLinks: node.childNodes.map((childNode) => { + if (childNode.type === SitemapTreeNodeType.CATEGORY) { + return { + label: '', + href: '', + childLinks: [], + } + } + if (childNode.type === SitemapTreeNodeType.URL) { + return { + label: childNode.label, + href: childNode.url, + childLinks: [], + } + } + + const entryNode = { + label: '', + href: '', + entryId: childNode.entryId, + childLinks: [], + } + + const nodeList = entryNodes.get(childNode.entryId) ?? [] + nodeList.push(entryNode) + entryNodes.set(childNode.entryId, nodeList) + + return entryNode + }), + } + } + + if (node.type === SitemapTreeNodeType.URL) { + return { + label: node.label, + childLinks: [], + } + } + + const entryNode = { + label: '', + href: '', + entryId: node.entryId, + childLinks: [], + } + + const nodeList = entryNodes.get(node.entryId) ?? [] + nodeList.push(entryNode) + entryNodes.set(node.entryId, nodeList) + + return entryNode + }), + } + + const parentSubpageResponse = + await this.contentfulRepository.getLocalizedEntries( + input.lang, + { + content_type: 'organizationParentSubpage', + 'sys.id[in]': Array.from(entryNodes.keys()).join(','), + limit: 1000, + }, + 1, + ) + + for (const parentSubpage of parentSubpageResponse.items) { + const nodeList = entryNodes.get(parentSubpage.sys.id) + if ( + !nodeList || + !parentSubpage.fields.slug || + !parentSubpage.fields.title + ) { + continue + } + for (const node of nodeList) { + node.label = parentSubpage.fields.title + node.href = `/${getOrganizationPageUrlPrefix(input.lang)}/${ + input.organizationPageSlug + }/${parentSubpage.fields.slug}` + } + } + + // Prune empty values + result.childCategories = result.childCategories.filter((childCategory) => { + childCategory.childLinks = childCategory.childLinks.filter( + (childLink) => { + return childLink.href && childLink.label + }, + ) + return childCategory.label && childCategory.childLinks.length > 0 + }) + return result } } diff --git a/libs/cms/src/lib/cms.resolver.ts b/libs/cms/src/lib/cms.resolver.ts index 55720481a4e4..cc26a42e6209 100644 --- a/libs/cms/src/lib/cms.resolver.ts +++ b/libs/cms/src/lib/cms.resolver.ts @@ -128,8 +128,14 @@ import { GetSingleGrantInput } from './dto/getSingleGrant.input' import { GrantList } from './models/grantList.model' import { OrganizationParentSubpage } from './models/organizationParentSubpage.model' import { GetOrganizationParentSubpageInput } from './dto/getOrganizationParentSubpage.input' -import { OrganizationPageStandaloneSitemap } from './models/organizationPageStandaloneSitemap.model' -import { GetOrganizationPageStandaloneSitemapLevel1Input } from './dto/getOrganizationPageStandaloneSitemap.input' +import { + OrganizationPageStandaloneSitemap, + OrganizationPageStandaloneSitemapLevel2, +} from './models/organizationPageStandaloneSitemap.model' +import { + GetOrganizationPageStandaloneSitemapLevel1Input, + GetOrganizationPageStandaloneSitemapLevel2Input, +} from './dto/getOrganizationPageStandaloneSitemap.input' const defaultCache: CacheControlOptions = { maxAge: CACHE_CONTROL_MAX_AGE } @@ -729,6 +735,16 @@ export class CmsResolver { input, ) } + + @CacheControl(defaultCache) + @Query(() => OrganizationPageStandaloneSitemapLevel2, { nullable: true }) + getOrganizationPageStandaloneSitemapLevel2( + @Args('input') input: GetOrganizationPageStandaloneSitemapLevel2Input, + ): Promise { + return this.cmsContentfulService.getOrganizationPageStandaloneSitemapLevel2( + input, + ) + } } @Resolver(() => LatestNewsSlice) diff --git a/libs/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.ts b/libs/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.ts index 761511383a48..e68109d730d2 100644 --- a/libs/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.ts +++ b/libs/cms/src/lib/dto/getOrganizationPageStandaloneSitemap.input.ts @@ -16,3 +16,10 @@ export class GetOrganizationPageStandaloneSitemapLevel1Input { @IsString() lang: ElasticsearchIndexLocale = 'is' } + +@InputType() +export class GetOrganizationPageStandaloneSitemapLevel2Input extends GetOrganizationPageStandaloneSitemapLevel1Input { + @Field() + @IsString() + subcategorySlug!: string +} diff --git a/libs/cms/src/lib/models/organizationPageStandaloneSitemap.model.ts b/libs/cms/src/lib/models/organizationPageStandaloneSitemap.model.ts index 197fee9b9f9f..45b76141678e 100644 --- a/libs/cms/src/lib/models/organizationPageStandaloneSitemap.model.ts +++ b/libs/cms/src/lib/models/organizationPageStandaloneSitemap.model.ts @@ -18,3 +18,33 @@ export class OrganizationPageStandaloneSitemap { @CacheField(() => [OrganizationPageStandaloneSitemapLink]) childLinks!: OrganizationPageStandaloneSitemapLink[] } + +@ObjectType() +export class OrganizationPageStandaloneSitemapLevel2Link { + @Field() + label!: string + + @Field() + href!: string +} + +@ObjectType() +export class OrganizationPageStandaloneSitemapLevel2Category { + @Field() + label!: string + + @Field(() => String, { nullable: true }) + href?: string | null + + @CacheField(() => [OrganizationPageStandaloneSitemapLevel2Link]) + childLinks!: OrganizationPageStandaloneSitemapLevel2Link[] +} + +@ObjectType() +export class OrganizationPageStandaloneSitemapLevel2 { + @Field() + label!: string + + @CacheField(() => [OrganizationPageStandaloneSitemapLevel2Category]) + childCategories!: OrganizationPageStandaloneSitemapLevel2Category[] +} From 86cec0795956158765f71631105f9b763b537cd8 Mon Sep 17 00:00:00 2001 From: runarvestmann Date: Mon, 2 Dec 2024 14:40:21 +0000 Subject: [PATCH 5/8] Edit breadcrumbs --- .../Organization/Standalone/Level2Sitemap.tsx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/web/screens/Organization/Standalone/Level2Sitemap.tsx b/apps/web/screens/Organization/Standalone/Level2Sitemap.tsx index dc5713d7ea37..40f72761af7e 100644 --- a/apps/web/screens/Organization/Standalone/Level2Sitemap.tsx +++ b/apps/web/screens/Organization/Standalone/Level2Sitemap.tsx @@ -19,7 +19,6 @@ import { QueryGetOrganizationPageArgs, QueryGetOrganizationPageStandaloneSitemapLevel2Args, } from '@island.is/web/graphql/schema' -import { useLinkResolver } from '@island.is/web/hooks' import useContentfulId from '@island.is/web/hooks/useContentfulId' import { StandaloneLayout } from '@island.is/web/layouts/organization/standalone' import type { Screen, ScreenContext } from '@island.is/web/types' @@ -49,15 +48,8 @@ const StandaloneLevel2Sitemap: Screen< StandaloneLevel2SitemapProps, StandaloneLevel2SitemapScreenContext > = ({ organizationPage, category, sitemap }) => { - const { linkResolver } = useLinkResolver() - const breadcrumbItems: BreadCrumbItem[] = useMemo(() => { - const items: BreadCrumbItem[] = [ - { - title: organizationPage.title, - href: linkResolver('organizationpage', [organizationPage.slug]).href, - }, - ] + const items: BreadCrumbItem[] = [] if (category) { items.push({ @@ -66,7 +58,7 @@ const StandaloneLevel2Sitemap: Screen< }) } return items - }, [category, linkResolver, organizationPage.slug, organizationPage.title]) + }, [category]) return ( Date: Mon, 2 Dec 2024 14:51:35 +0000 Subject: [PATCH 6/8] Add comment --- libs/cms/src/lib/cms.contentful.service.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/cms/src/lib/cms.contentful.service.ts b/libs/cms/src/lib/cms.contentful.service.ts index d6c05a8cf2e0..e78ca9ccef67 100644 --- a/libs/cms/src/lib/cms.contentful.service.ts +++ b/libs/cms/src/lib/cms.contentful.service.ts @@ -1338,6 +1338,7 @@ export class CmsContentfulService { label: node.label, childLinks: node.childNodes.map((childNode) => { if (childNode.type === SitemapTreeNodeType.CATEGORY) { + // Category at depth 3 should be empty so it gets pruned at a later stage return { label: '', href: '', @@ -1371,6 +1372,7 @@ export class CmsContentfulService { if (node.type === SitemapTreeNodeType.URL) { return { label: node.label, + href: node.url, childLinks: [], } } @@ -1410,6 +1412,7 @@ export class CmsContentfulService { ) { continue } + for (const node of nodeList) { node.label = parentSubpage.fields.title node.href = `/${getOrganizationPageUrlPrefix(input.lang)}/${ From e29cff67c9d3cd3b0a6db8ed3e12c42b4261a1b1 Mon Sep 17 00:00:00 2001 From: runarvestmann Date: Mon, 2 Dec 2024 14:53:35 +0000 Subject: [PATCH 7/8] Add comment --- libs/cms/src/lib/models/organizationParentSubpage.model.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/cms/src/lib/models/organizationParentSubpage.model.ts b/libs/cms/src/lib/models/organizationParentSubpage.model.ts index a320aff2075a..990aadedc9e7 100644 --- a/libs/cms/src/lib/models/organizationParentSubpage.model.ts +++ b/libs/cms/src/lib/models/organizationParentSubpage.model.ts @@ -35,6 +35,7 @@ export const mapOrganizationParentSubpage = ({ fields.pages ?.filter( (page) => + // Child pages should belong to the same organization page page.fields.organizationPage?.sys?.id === fields.organizationPage?.sys?.id && Boolean(page.fields.organizationPage?.fields?.slug) && From 21140a958e88b334a7020bcb980f05b6c07712c3 Mon Sep 17 00:00:00 2001 From: runarvestmann Date: Mon, 2 Dec 2024 16:04:21 +0000 Subject: [PATCH 8/8] Update error handler constant --- libs/cms/src/lib/cms.contentful.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/cms/src/lib/cms.contentful.service.ts b/libs/cms/src/lib/cms.contentful.service.ts index e78ca9ccef67..f1e40230d6d8 100644 --- a/libs/cms/src/lib/cms.contentful.service.ts +++ b/libs/cms/src/lib/cms.contentful.service.ts @@ -1297,7 +1297,7 @@ export class CmsContentfulService { const response = await this.contentfulRepository .getLocalizedEntries(input.lang, params) - .catch(errorHandler('getOrganizationPageStandaloneSitemapLevel1')) + .catch(errorHandler('getOrganizationPageStandaloneSitemapLevel2')) const tree = response.items?.[0]?.fields.sitemap?.fields.tree as SitemapTree