diff --git a/examples/nuxt-app/test/features/site/feature-flags.feature b/examples/nuxt-app/test/features/site/feature-flags.feature index 056abdbc69..beee6eb0f7 100644 --- a/examples/nuxt-app/test/features/site/feature-flags.feature +++ b/examples/nuxt-app/test/features/site/feature-flags.feature @@ -120,3 +120,17 @@ Feature: Site feature flags | 4.1 Many Talents - demo | /many-talents-demo | | 5.1 Another menu - demo | /another-demo | | 4.2 More Talents - demo | /more-talents-demo | + + @mockserver + Scenario: Feature flags can be set per site section + Given the site endpoint returns fixture "/site/reference" with status 200 + And I load the page fixture with "/landingpage/home" + And the site sections share links are set to included WhatsApp + And the page endpoint for path "/section-page" returns the loaded fixture + When I visit the page "/section-page" + Then the sidebar social share links should display as follows + | link | visible | + | Facebook | true | + | X (formerly Twitter) | true | + | LinkedIn | true | + | WhatsApp | true | diff --git a/examples/nuxt-app/test/features/site/shared-elements.feature b/examples/nuxt-app/test/features/site/shared-elements.feature index d25c336b48..49d311b0a1 100644 --- a/examples/nuxt-app/test/features/site/shared-elements.feature +++ b/examples/nuxt-app/test/features/site/shared-elements.feature @@ -9,6 +9,30 @@ Feature: Shared site elements Given I visit the page "/" Then the page title should be "Demo Landing Page | vic.gov.au" + @mockserver + Scenario: Quick Exit (default: disabled site wide) + Given the site endpoint returns fixture "/site/shared-elements" with status 200 + And the page endpoint for path "/" returns fixture "/landingpage/home" with status 200 + Given I visit the page "/" + Then the quick exit should not be displayed + + @mockserver + Scenario: Quick Exit (enabled site wide) + Given I load the site fixture with "/site/shared-elements" + And the page endpoint for path "/" returns fixture "/landingpage/home" with status 200 + And the site wide quick exit is enabled + And the site endpoint returns the loaded fixture + Given I visit the page "/" + Then the quick exit should be displayed + + @mockserver + Scenario: Quick Exit (enabled in site section) + Given the site endpoint returns fixture "/site/shared-elements" with status 200 + And I load the page fixture with "/landingpage/home" + And the site section quick exit is enabled + And the page endpoint for path "/section-page" returns the loaded fixture + Given I visit the page "/section-page" + Then the quick exit should be displayed @mockserver Scenario: Breadcrumbs (page exists in menu) diff --git a/examples/nuxt-app/test/features/site/theme.feature b/examples/nuxt-app/test/features/site/theme.feature index 33eee54e48..c87c36d2da 100644 --- a/examples/nuxt-app/test/features/site/theme.feature +++ b/examples/nuxt-app/test/features/site/theme.feature @@ -21,6 +21,15 @@ Feature: Site theme Given I visit the page "/" Then the site header background color should be "rgb(225, 57, 64)" + @mockserver + Scenario: The theme can be set per site section + Given the site endpoint returns fixture "/site/reference" with status 200 + And I load the page fixture with "/landingpage/home" + And the site sections primary colour is set to "#1962A3" + And the page endpoint for path "/section-page" returns the loaded fixture + When I visit the page "/section-page" + Then the site header background color should be "rgb(25, 98, 163)" + @mockserver Scenario: Feature flags set neutral theme Given the site endpoint returns fixture "/site/neutral-footer" with status 200 diff --git a/packages/nuxt-ripple/components/TideContentPage.vue b/packages/nuxt-ripple/components/TideContentPage.vue index 1059588bb0..85a2010115 100644 --- a/packages/nuxt-ripple/components/TideContentPage.vue +++ b/packages/nuxt-ripple/components/TideContentPage.vue @@ -43,10 +43,18 @@ import { useTideSite, useTidePage } from '#imports' import { computed } from 'vue' import { pascalCase, pascalCaseTransformMerge } from 'change-case' +import { defu as defuMerge } from 'defu' -const site = await useTideSite() +let _site = await useTideSite() const page = await useTidePage() +// Allow page site section settings to override the main site settings +const site = computed(() => { + return _site && page?.siteSection?.siteOverrides + ? defuMerge(page.siteSection.siteOverrides, _site) + : _site +}) + const componentName = computed( () => page && diff --git a/packages/nuxt-ripple/mapping/base/index.ts b/packages/nuxt-ripple/mapping/base/index.ts index 8b9ad69c0e..cd4fc285ff 100644 --- a/packages/nuxt-ripple/mapping/base/index.ts +++ b/packages/nuxt-ripple/mapping/base/index.ts @@ -23,7 +23,7 @@ import { includes as sidebarSiteSectionNavIncludes } from './sidebar-site-section-nav/sidebar-site-section-nav-mapping.js' import TidePageMeta from './page-meta.js' -import { getSiteSection } from '@dpc-sdp/ripple-tide-api' +import { getSiteKeyValues, getSiteSection } from '@dpc-sdp/ripple-tide-api' export const tidePageBaseMapping = ({ // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -74,7 +74,13 @@ export const tidePageBaseMapping = ({ return { id: siteData.drupal_internal__tid, - name: siteData.name + name: siteData.name, + siteOverrides: { + showQuickExit: siteData?.field_site_show_exit_site || null, + theme: getSiteKeyValues('field_site_theme_values', siteData) || {}, + featureFlags: + getSiteKeyValues('field_site_feature_flags', siteData) || {} + } } }, ...TidePageMeta, @@ -93,6 +99,7 @@ export const tidePageBaseIncludes = ({ withSidebarSiteSectionNav = false } = {}) => { return [ + 'field_node_site', ...(withTopicTags ? topicTagsIncludes : []), ...(withSidebarContacts ? sidebarContactsIncludes : []), ...(withSidebarRelatedLinks ? sidebarRelatedLinksIncludes : []), diff --git a/packages/nuxt-ripple/mapping/base/sidebar-site-section-nav/sidebar-site-section-nav-mapping.ts b/packages/nuxt-ripple/mapping/base/sidebar-site-section-nav/sidebar-site-section-nav-mapping.ts index 3397da6f99..8e46298fa6 100644 --- a/packages/nuxt-ripple/mapping/base/sidebar-site-section-nav/sidebar-site-section-nav-mapping.ts +++ b/packages/nuxt-ripple/mapping/base/sidebar-site-section-nav/sidebar-site-section-nav-mapping.ts @@ -27,7 +27,4 @@ export const map = async (src, tidePageApi: TidePageApi) => { } } -export const includes = [ - 'field_node_site', - 'field_node_site.field_site_main_menu' -] +export const includes = ['field_node_site.field_site_main_menu'] diff --git a/packages/nuxt-ripple/types.d.ts b/packages/nuxt-ripple/types.d.ts index a664bdeeb5..f25f40db60 100644 --- a/packages/nuxt-ripple/types.d.ts +++ b/packages/nuxt-ripple/types.d.ts @@ -1,5 +1,9 @@ import type { AxiosInstance } from 'axios' -import { IRplFeatureFlags, IRplTideModuleMapping } from 'ripple-tide-api/types' +import type { + IRplFeatureFlags, + IRplTideModuleMapping, + TideSiteSection +} from '@dpc-sdp/ripple-tide-api/types' import { TideAlert } from './src/mapping/alerts/site-alerts-mapping' import { TideContact } from './src/mapping/sidebar-contacts/sidebar-contacts-mapping-types' import { TideTopicTag } from './src/mapping/topic-tags/topic-tags-mapping' @@ -105,6 +109,7 @@ export interface TideHeroHeader { } export interface TidePageBase { + type: string title: string created: string changed: string @@ -116,6 +121,7 @@ export interface TidePageBase { contacts?: TideContact[] relatedLinks?: any[] } + siteSection: TideSiteSection [key: string]: unknown } diff --git a/packages/ripple-test-utils/step_definitions/common/shared-elements.ts b/packages/ripple-test-utils/step_definitions/common/shared-elements.ts index 1ddaf96c56..cb9f3bb8ab 100644 --- a/packages/ripple-test-utils/step_definitions/common/shared-elements.ts +++ b/packages/ripple-test-utils/step_definitions/common/shared-elements.ts @@ -220,3 +220,33 @@ Given( }) } ) + +Given('the site wide quick exit is enabled', () => { + cy.get('@siteFixture').then((response) => { + set(response, 'showQuickExit', true) + }) +}) + +Given('the site section quick exit is enabled', () => { + cy.get('@pageFixture').then((response) => { + set(response, 'siteSection.siteOverrides.showQuickExit', true) + }) +}) + +Then('the quick exit should be displayed', () => { + cy.get('.rpl-primary-nav__quick-exit').should('be.visible') +}) + +Then('the quick exit should not be displayed', () => { + cy.get('.rpl-primary-nav__quick-exit').should('not.exist') +}) + +Given('the site sections share links are set to included WhatsApp', () => { + cy.get('@pageFixture').then((response) => { + set( + response, + 'siteSection.siteOverrides.featureFlags[socialShare.WhatsApp]', + true + ) + }) +}) diff --git a/packages/ripple-test-utils/step_definitions/common/site/theme.ts b/packages/ripple-test-utils/step_definitions/common/site/theme.ts index fbf5b33e5e..a315afd956 100644 --- a/packages/ripple-test-utils/step_definitions/common/site/theme.ts +++ b/packages/ripple-test-utils/step_definitions/common/site/theme.ts @@ -1,4 +1,5 @@ -import { Then } from '@badeball/cypress-cucumber-preprocessor' +import { Given, Then } from '@badeball/cypress-cucumber-preprocessor' +import { set } from 'lodash-es' Then( 'the site header background color should be {string}', @@ -48,3 +49,12 @@ Then('the footer vic.gov.au logo should not be displayed', () => { Then('the cobrand logo should be displayed', () => { cy.get('.rpl-primary-nav__secondary-logo-image').should('exist') }) + +Given( + 'the site sections primary colour is set to {string}', + (value: string) => { + cy.get('@pageFixture').then((response) => { + set(response, 'siteSection.siteOverrides.theme["rpl-clr-primary"]', value) + }) + } +) diff --git a/packages/ripple-tide-api/types.d.ts b/packages/ripple-tide-api/types.d.ts index c55ced3f9d..d185e7c0be 100644 --- a/packages/ripple-tide-api/types.d.ts +++ b/packages/ripple-tide-api/types.d.ts @@ -41,7 +41,7 @@ export interface TideSiteData { theme: { [key: string]: string } - featureFlags: RplFeatureFlags + featureFlags: IRplFeatureFlags socialImages: { twitter: any og: any @@ -130,9 +130,16 @@ export type TidePropRange = { to: string | number } +export type TideSiteSectionOverrides = { + showQuickExit: boolean + theme: Record + featureFlags: IRplFeatureFlags +} + export type TideSiteSection = { id: string name: string + siteOverrides: TideSiteSectionOverrides } export interface TideSocialShare {