diff --git a/CHANGELOG.md b/CHANGELOG.md index 84bf4afebd..4d3998acbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v2.21.0 + +[compare changes](https://github.com/dpc-sdp/ripple-framework/compare/2.21.0...v2.21.0) + ## v2.20.0 [compare changes](https://github.com/dpc-sdp/ripple-framework/compare/2.20.0...v2.20.0) diff --git a/examples/nuxt-app/cypress.config.mjs b/examples/nuxt-app/cypress.config.mjs index 96355fdc5e..d750c55c8a 100644 --- a/examples/nuxt-app/cypress.config.mjs +++ b/examples/nuxt-app/cypress.config.mjs @@ -21,5 +21,9 @@ export default defineConfig({ return config } }, + retries: { + runMode: 3, + openMode: 0 + }, blockHosts: ['*youtube.com', '*doubleclick.net'] }) diff --git a/examples/nuxt-app/layers/ripple-ui-forms-ext/__test__/fixtures/webform.json b/examples/nuxt-app/layers/ripple-ui-forms-ext/__test__/fixtures/webform.json index 8218186cf1..d697dec6fc 100644 --- a/examples/nuxt-app/layers/ripple-ui-forms-ext/__test__/fixtures/webform.json +++ b/examples/nuxt-app/layers/ripple-ui-forms-ext/__test__/fixtures/webform.json @@ -24,7 +24,6 @@ "name": "Demo Site", "siteOverrides": { "showQuickExit": null, - "theme": {}, "featureFlags": {} } }, diff --git a/examples/nuxt-app/test/features/landingpage/custom-collection.feature b/examples/nuxt-app/test/features/landingpage/custom-collection.feature index 16b9334f40..cfae917ec1 100644 --- a/examples/nuxt-app/test/features/landingpage/custom-collection.feature +++ b/examples/nuxt-app/test/features/landingpage/custom-collection.feature @@ -129,3 +129,48 @@ Feature: Custom Collection When I visit the page "/filter-only" Then the custom collection component results count should be hidden + + @mockserver + Example: Autocomplete suggestions are disabled by default + Given the page endpoint for path "/custom-collection-suggestions" returns fixture "/landingpage/custom-collection/page" with status 200 + And the search network request is stubbed with fixture "/landingpage/custom-collection/response" and status 200 + + When I visit the page "/custom-collection-suggestions" + Then I type "The" into the custom collection input + And the search suggestions should not be displayed + + @mockserver + Example: Autocomplete suggestions can be enabled + Given I load the page fixture with "/landingpage/custom-collection/page" + And the search autocomplete request is stubbed with "/landingpage/custom-collection/response-suggestions" fixture + And the custom collection config has "suggestions.enabled" set to "true" + And the search network request is stubbed with fixture "/landingpage/custom-collection/response" and status 200 + Then the page endpoint for path "/custom-collection-suggestions" returns the loaded fixture + + When I visit the page "/custom-collection-suggestions" + Then I type "gover" into the custom collection input + Then the search autocomplete request should be called with the "/landingpage/custom-collection/request-suggestions" fixture + And the search suggestions displayed should include + | govern | + | government | + | government agency | + + @mockserver + Example: Autocomplete minimum characters can be customised + Given I load the page fixture with "/landingpage/custom-collection/page" + And the search autocomplete request is stubbed with "/landingpage/custom-collection/response-suggestions" fixture + And the custom collection config has "suggestions.enabled" set to "true" + And the custom collection config has "suggestions.minCharacters" set to "5" + And the search network request is stubbed with fixture "/landingpage/custom-collection/response" and status 200 + Then the page endpoint for path "/custom-collection-suggestions" returns the loaded fixture + + When I visit the page "/custom-collection-suggestions" + Then I type "gov" into the custom collection input + Then the search suggestions should not be displayed + + When I type "er" into the custom collection input + Then the search autocomplete request should be called with the "/landingpage/custom-collection/request-suggestions" fixture + And the search suggestions displayed should include + | govern | + | government | + | government agency | diff --git a/examples/nuxt-app/test/features/maps/maps.feature b/examples/nuxt-app/test/features/maps/maps.feature index ce1b53d273..47cfbdfe3d 100644 --- a/examples/nuxt-app/test/features/maps/maps.feature +++ b/examples/nuxt-app/test/features/maps/maps.feature @@ -21,7 +21,7 @@ Feature: Custom collection map component And the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is delayed by 1000 milliseconds and stubbed with fixture "/site/search-response", status 200 and alias "searchReq" Given I visit the page "/map" Then the map loading screen should be displayed - When I wait 2 seconds + And the map is loaded Then the map should be displayed @mockserver @@ -31,7 +31,7 @@ Feature: Custom collection map component Given the page endpoint for path "/map" returns the loaded fixture Given the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/maps/simple-map-results" and status 200 as alias "searchReq" Given I visit the page "/map" - When I wait 2 seconds + And the map is loaded When I click the map component at coordinates 517 242 When I wait 2 seconds Then the map matches the image snapshot "map-popup-type-popover" @@ -43,7 +43,7 @@ Feature: Custom collection map component Given the page endpoint for path "/map" returns the loaded fixture Given the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/maps/simple-map-results" and status 200 as alias "searchReq" Given I visit the page "/map" - When I wait 2 seconds + And the map is loaded When I click the map component at coordinates 517 242 When I wait 2 seconds Then the map matches the image snapshot "map-popup-type-sidebar" @@ -56,7 +56,7 @@ Feature: Custom collection map component Given the page endpoint for path "/map" returns the loaded fixture Given the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/maps/simple-map-results" and status 200 as alias "searchReq" Given I visit the page "/map" - When I wait 2 seconds + And the map is loaded When I click the map component at coordinates 663 242 When I wait 2 seconds Then the map matches the image snapshot "map-popup-type-popover-with-sidepanel" @@ -69,7 +69,7 @@ Feature: Custom collection map component Given the page endpoint for path "/map" returns the loaded fixture Given the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/maps/simple-map-results" and status 200 as alias "searchReq" Given I visit the page "/map" - When I wait 2 seconds + And the map is loaded When I click the map component at coordinates 663 242 When I wait 2 seconds Then the map matches the image snapshot "map-popup-type-sidebar-with-sidepanel" @@ -81,7 +81,7 @@ Feature: Custom collection map component Given the page endpoint for path "/map" returns the loaded fixture Given the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/maps/simple-map-results" and status 200 as alias "searchReq" Given I visit the page "/map" - When I wait 2 seconds + And the map is loaded When I click the map component at coordinates 606 424 When I wait 2 seconds Then the map matches the image snapshot "map-popup-type-sidebar-with-sidepanel-double-pin" @@ -94,6 +94,7 @@ Feature: Custom collection map component Given the page endpoint for path "/map" returns the loaded fixture Given the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/maps/simple-map-results" and status 200 as alias "searchReq" Given I visit the page "/map" + And the map is loaded Given I click the side panel item with text "Single Pin Test" When I wait 2 seconds Then the map matches the image snapshot "map-sidepanel-item-click" @@ -107,7 +108,7 @@ Feature: Custom collection map component Then the page endpoint for path "/map" returns the loaded fixture And the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/maps/simple-map-results" and status 200 as alias "searchReq" Given I visit the page "/map" - When I wait 2 seconds + And the map is loaded Then I click the map component at coordinates 545 385 And I wait 1 seconds Then I click the map component at coordinates 660 320 @@ -121,7 +122,7 @@ Feature: Custom collection map component Then the page endpoint for path "/map" returns the loaded fixture And the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/maps/simple-map-results" and status 200 as alias "searchReq" Given I visit the page "/map?location[center]=15809362.126037747&location[center]=-4543542.166789566" - When I wait 2 seconds + And the map is loaded Then the map matches the image snapshot "map-initial-location-results-hook" @mockserver @@ -133,7 +134,7 @@ Feature: Custom collection map component Then the page endpoint for path "/map" returns the loaded fixture And the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/maps/simple-map-results" and status 200 as alias "searchReq" Given I visit the page "/map" - And I wait 2 seconds + And the map is loaded Then the map matches the image snapshot "map-custom-default-extent" @mockserver diff --git a/examples/nuxt-app/test/features/maps/vsba.feature b/examples/nuxt-app/test/features/maps/vsba.feature index fd97dbc890..a16894687d 100644 --- a/examples/nuxt-app/test/features/maps/vsba.feature +++ b/examples/nuxt-app/test/features/maps/vsba.feature @@ -87,9 +87,9 @@ Feature: School buildings map Scenario: Click on cluster should zoom in Given the "/api/tide/elasticsearch/elasticsearch_index_develop_node/_search" network request is stubbed with fixture "/map-table/vsba/response-all" and status 200 as alias "searchReq" And I visit the page "/map" - When I wait 4 seconds + When the map is loaded When I click the map component at coordinates 650 429 - When I wait 8 seconds + When I wait 4 seconds Then the map matches the image snapshot "map-cluster-zoom" @mockserver diff --git a/examples/nuxt-app/test/features/search-listing/filters.feature b/examples/nuxt-app/test/features/search-listing/filters.feature index 24cea2d7a8..3f87344d96 100644 --- a/examples/nuxt-app/test/features/search-listing/filters.feature +++ b/examples/nuxt-app/test/features/search-listing/filters.feature @@ -14,7 +14,6 @@ Feature: Search listing - Filter When I visit the page "/filters" Then the search listing filters section should be open - And the filters toggle should be hidden @mockserver Example: Raw filter - Should reflect the value from the URL diff --git a/examples/nuxt-app/test/features/search-listing/suggestions.feature b/examples/nuxt-app/test/features/search-listing/suggestions.feature index 7bc0933a28..fa6f3fb6b1 100644 --- a/examples/nuxt-app/test/features/search-listing/suggestions.feature +++ b/examples/nuxt-app/test/features/search-listing/suggestions.feature @@ -7,7 +7,18 @@ Feature: Search listing - Suggestions And I am using a "macbook-16" device @mockserver - Example: Displays autocomplete suggestions + Example: Autocomplete suggestions are disabled by default + Given the page endpoint for path "/no-suggestions" returns fixture "/search-listing/suggestions/page-no-suggestions" with status 200 + And the search network request is stubbed with fixture "/search-listing/suggestions/search-response" and status 200 + + When I visit the page "/no-suggestions" + Then the search listing page should have 2 results + + When I type "The" into the search input + Then the search suggestions should not be displayed + + @mockserver + Example: Autocomplete suggestions can be enabled Given the page endpoint for path "/suggestions" returns fixture "/search-listing/suggestions/page-suggestions" with status 200 And the search network request is stubbed with fixture "/search-listing/suggestions/search-response" and status 200 And the search autocomplete request is stubbed with "/search-listing/suggestions/response" fixture @@ -32,19 +43,21 @@ Feature: Search listing - Suggestions And the search autocomplete request is stubbed with "/search-listing/suggestions/response" fixture When I visit the page "/suggestions-override" - And I type "The" into the search input + And I type "There" into the search input Then the search autocomplete request should be called with the "/search-listing/suggestions/request-override" fixture @mockserver - Example: Autocomplete suggestions can be disabled - Given the page endpoint for path "/no-suggestions" returns fixture "/search-listing/suggestions/page-no-suggestions" with status 200 + Example: Autocomplete minimum characters can be customised + Given the page endpoint for path "/suggestions-characters" returns fixture "/search-listing/suggestions/page-suggestions-override" with status 200 And the search network request is stubbed with fixture "/search-listing/suggestions/search-response" and status 200 + And the search autocomplete request is stubbed with "/search-listing/suggestions/response" fixture - When I visit the page "/no-suggestions" - Then the search listing page should have 2 results + When I visit the page "/suggestions-characters" + Then I type "The" into the search input + And the search suggestions should not be displayed - When I type "The" into the search input - Then the search suggestions should not be displayed + When I type "re" into the search input + Then the search suggestions should be displayed @mockserver Example: Search bar max input length diff --git a/examples/nuxt-app/test/features/site/analytics.feature b/examples/nuxt-app/test/features/site/analytics.feature index f38ae3c640..0fa142d13d 100644 --- a/examples/nuxt-app/test/features/site/analytics.feature +++ b/examples/nuxt-app/test/features/site/analytics.feature @@ -9,8 +9,12 @@ Feature: Analytics And the page endpoint for path "/" returns fixture "/landingpage/home" with status 200 Given I visit the page "/" Then the dataLayer should include the following events - | event | page_title | page_url | content_type | content_status | - | routeChange | Demo Landing Page | / | landing_page | published | + | event | page_title | page_url | content_type | content_status | content_topic | + | routeChange | Demo Landing Page | / | landing_page | published | Demo Topic | + Then the dataLayer should have the following tags + | name | + | Demo Tag | + | Another Demo Tag | @mockserver Scenario: Breadcrumbs diff --git a/examples/nuxt-app/test/features/site/shared-elements.feature b/examples/nuxt-app/test/features/site/shared-elements.feature index ea4f55c0b9..f6ed7ccb4d 100644 --- a/examples/nuxt-app/test/features/site/shared-elements.feature +++ b/examples/nuxt-app/test/features/site/shared-elements.feature @@ -101,9 +101,10 @@ Feature: Shared site elements Given I visit the page "/some-random-page" Then the page should have the following topic tags - | text | url | - | Demo Topic | /topic/demo-topic | - | Demo Tag | /tags/demo-tag | + | text | url | + | Demo Topic | /topic/demo-topic | + | Demo Tag | /tags/demo-tag | + | Another Demo Tag | /tags/another-demo-tag | @mockserver Scenario: Content Rating (visible) diff --git a/examples/nuxt-app/test/features/site/theme.feature b/examples/nuxt-app/test/features/site/theme.feature index fea9629891..94eb205127 100644 --- a/examples/nuxt-app/test/features/site/theme.feature +++ b/examples/nuxt-app/test/features/site/theme.feature @@ -21,15 +21,6 @@ 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/examples/nuxt-app/test/fixtures/landingpage/custom-collection/request-suggestions.json b/examples/nuxt-app/test/fixtures/landingpage/custom-collection/request-suggestions.json new file mode 100644 index 0000000000..67096fdab3 --- /dev/null +++ b/examples/nuxt-app/test/fixtures/landingpage/custom-collection/request-suggestions.json @@ -0,0 +1,11 @@ +{ + "query": "gover", + "types": { + "documents": { + "fields": [ + "title" + ] + } + }, + "size": 8 +} diff --git a/examples/nuxt-app/test/fixtures/landingpage/custom-collection/response-suggestions.json b/examples/nuxt-app/test/fixtures/landingpage/custom-collection/response-suggestions.json new file mode 100644 index 0000000000..8567242e47 --- /dev/null +++ b/examples/nuxt-app/test/fixtures/landingpage/custom-collection/response-suggestions.json @@ -0,0 +1,18 @@ +{ + "results": { + "documents": [ + { + "suggestion": "govern" + }, + { + "suggestion": "government" + }, + { + "suggestion": "government agency" + } + ] + }, + "meta": { + "request_id": "9b60a1b5a0ec63cc9b61f39236649a04" + } +} diff --git a/examples/nuxt-app/test/fixtures/landingpage/home.json b/examples/nuxt-app/test/fixtures/landingpage/home.json index d9f49b2691..793f0e3d4c 100644 --- a/examples/nuxt-app/test/fixtures/landingpage/home.json +++ b/examples/nuxt-app/test/fixtures/landingpage/home.json @@ -14,6 +14,24 @@ { "text": "Demo Tag", "url": "/tags/demo-tag" + }, + { + "text": "Another Demo Tag", + "url": "/tags/another-demo-tag" + } + ], + "topic": { + "text": "Demo Topic", + "url": "/topic/demo-topic" + }, + "tags": [ + { + "text": "Demo Tag", + "url": "/tags/demo-tag" + }, + { + "text": "Another Demo Tag", + "url": "/tags/another-demo-tag" } ], "sidebar": { diff --git a/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-no-suggestions.json b/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-no-suggestions.json index 8427a6a120..279e9557c6 100644 --- a/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-no-suggestions.json +++ b/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-no-suggestions.json @@ -9,10 +9,7 @@ "config": { "searchListingConfig": { "index": "suggestion_index", - "resultsPerPage": 10, - "suggestions": { - "enabled": false - } + "resultsPerPage": 10 }, "queryConfig": { "multi_match": { diff --git a/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-suggestions-override.json b/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-suggestions-override.json index 20351c3c93..4b0de1e98f 100644 --- a/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-suggestions-override.json +++ b/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-suggestions-override.json @@ -12,7 +12,8 @@ "resultsPerPage": 10, "suggestions": { "enabled": true, - "key": "suggestion_override_key" + "key": "suggestion_override_key", + "minCharacters": 5 } }, "queryConfig": { diff --git a/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-suggestions.json b/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-suggestions.json index 279e9557c6..892e031fa9 100644 --- a/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-suggestions.json +++ b/examples/nuxt-app/test/fixtures/search-listing/suggestions/page-suggestions.json @@ -9,7 +9,10 @@ "config": { "searchListingConfig": { "index": "suggestion_index", - "resultsPerPage": 10 + "resultsPerPage": 10, + "suggestions": { + "enabled": true + } }, "queryConfig": { "multi_match": { diff --git a/examples/nuxt-app/test/fixtures/search-listing/suggestions/request-override.json b/examples/nuxt-app/test/fixtures/search-listing/suggestions/request-override.json index 846fbd529e..7f8e6631ce 100644 --- a/examples/nuxt-app/test/fixtures/search-listing/suggestions/request-override.json +++ b/examples/nuxt-app/test/fixtures/search-listing/suggestions/request-override.json @@ -1,5 +1,5 @@ { - "query": "The", + "query": "There", "types": { "documents": { "fields": [ diff --git a/lerna.json b/lerna.json index f8dda8f730..ddfc99c02e 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.20.0", + "version": "2.21.0", "npmClient": "pnpm", "exact": true, "command": { diff --git a/packages/eslint-config-ripple/package.json b/packages/eslint-config-ripple/package.json index 27a98fff5d..0ecf89e09d 100644 --- a/packages/eslint-config-ripple/package.json +++ b/packages/eslint-config-ripple/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/eslint-config-ripple", "description": "ESLint config for Ripple projects", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "index.js", diff --git a/packages/nuxt-ripple-analytics/lib/routeChange.ts b/packages/nuxt-ripple-analytics/lib/routeChange.ts index 5a323aa5e6..8c30adba33 100644 --- a/packages/nuxt-ripple-analytics/lib/routeChange.ts +++ b/packages/nuxt-ripple-analytics/lib/routeChange.ts @@ -4,6 +4,10 @@ import { getBreadcrumbs } from '#imports' const trimValue = (value: any) => typeof value === 'string' ? value.trim() : value +const mapTags = (items: { text: string }[]) => { + return (items || []).map((item) => item?.text) +} + export default function ({ route, site, page }): IRplAnalyticsEventPayload { const payload: IRplAnalyticsEventPayload = { event: 'routeChange', @@ -11,6 +15,8 @@ export default function ({ route, site, page }): IRplAnalyticsEventPayload { page_url: route.fullPath, content_type: page?.type, content_status: page?.status, + content_topic: page?.topic?.text, + content_tags: mapTags(page?.tags), publication_name: page?.publication?.text, search_term: trimValue(route.query?.q), site_section: page?.siteSection?.name, diff --git a/packages/nuxt-ripple-analytics/lib/tracker.ts b/packages/nuxt-ripple-analytics/lib/tracker.ts index 86b983f8f8..c3352ac743 100644 --- a/packages/nuxt-ripple-analytics/lib/tracker.ts +++ b/packages/nuxt-ripple-analytics/lib/tracker.ts @@ -32,6 +32,8 @@ export interface IRplAnalyticsEventPayload { status_code?: number content_type?: string content_status?: string + content_topic?: string + content_tags?: string[] search_term?: string site_section?: string publication_name?: string diff --git a/packages/nuxt-ripple-analytics/package.json b/packages/nuxt-ripple-analytics/package.json index ccbe0353c3..441289a6cf 100644 --- a/packages/nuxt-ripple-analytics/package.json +++ b/packages/nuxt-ripple-analytics/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/nuxt-ripple-analytics", "description": "Nuxt module for handling event tracking.", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "main": "./nuxt.config.ts", "repository": "https://github.com/dpc-sdp/ripple-framework", diff --git a/packages/nuxt-ripple-cli/package.json b/packages/nuxt-ripple-cli/package.json index d88ba765d2..f0befae67a 100644 --- a/packages/nuxt-ripple-cli/package.json +++ b/packages/nuxt-ripple-cli/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/nuxt-ripple-cli", "description": "A CLI for simplifying common setup and scaffolding tasks", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "./dist/index.js", @@ -21,11 +21,9 @@ "copyfiles": "^2.4.1", "enquirer": "^2.3.6", "hygen": "^6.2.11", - "jsonapi-parse": "^2.0.1", "mockttp": "^3.9.1", "npm-check-updates": "^16.10.16", "object-to-argv": "^2.0.0", - "rfg-api": "^0.5.3", "rimraf": "^4.4.1", "ts-node": "^10.7.0" } diff --git a/packages/nuxt-ripple-cli/src/commands/favicon/favicon.ts b/packages/nuxt-ripple-cli/src/commands/favicon/favicon.ts deleted file mode 100644 index aeea9bab89..0000000000 --- a/packages/nuxt-ripple-cli/src/commands/favicon/favicon.ts +++ /dev/null @@ -1,190 +0,0 @@ -import * as jsonapiParse from 'jsonapi-parse' -import fs from 'fs' -import path from 'path' -import { Readable } from 'stream' -import { finished } from 'stream/promises' -import { init as initRfgApi } from 'rfg-api' - -const { generateFavicon, createRequest } = initRfgApi() - -export interface generateOpts { - masterPath: string - outputPath: string - API_KEY: string - themeColour: string - siteName: string -} - -// Set config for RFG and call API -async function generate(opt: generateOpts): Promise { - console.info('Favicon: generating assets...') - - const iosConfig = { - pictureAspect: 'noChange' - } - - const safariConfig = { - pictureAspect: 'black_and_white', - backgroundColor: '#ffffff', - threshold: 60 - } - - const androidConfig = { - pictureAspect: 'noChange', - manifest: { - name: opt.siteName, - display: 'standalone', - orientation: 'portrait', - start_url: '/' - }, - assets: { - legacyIcon: false, - lowResolutionIcons: false - }, - theme_color: opt.themeColour - } - - const windowsConfig = { - pictureAspect: 'white_silhouette', - backgroundColor: opt.themeColour, - assets: { - windows80Ie10Tile: true, - windows10Ie11EdgeTiles: { - small: true, - medium: true, - big: true, - rectangle: true - } - } - } - - const faviconDesign = { - desktopBrowser: {}, - ios: iosConfig, - androidChrome: androidConfig, - safariPinnedTab: safariConfig, - windows: windowsConfig - } - - return generateFavicon( - createRequest({ - apiKey: opt.API_KEY, - masterPicture: opt.masterPath, - iconsPath: opt.outputPath, - design: faviconDesign, - settings: { usePathAsIs: false } - // versioning? - }), - path.resolve(process.cwd(), opt.outputPath || '.'), - async (err: any) => { - if (err) { - throw err - } - - // Remove outputPath from manifest files - for (const manifest of ['browserconfig.xml', 'site.webmanifest']) { - const path = `${opt.outputPath}/${manifest}`, - original = await fs.promises.readFile(path, 'utf8'), - updated = original.replace(new RegExp(opt.outputPath, 'g'), '') - await fs.promises.writeFile(path, updated, 'utf8') - } - - console.info('Favicon: generate complete!') - } - ) -} - -interface faviconArgs { - apiKey: string - baseUrl: string - siteId: string - publicPath: string -} - -// Main -export default async function favicon(args: faviconArgs) { - const publicFolderPath = args.publicPath - - if (!args.apiKey) { - console.info('Favicon: missing apiKey') - return - } - if (!args.baseUrl) { - console.info('Favicon: missing baseUrl') - return - } - if (!args.siteId) { - console.info('Favicon: missing siteId') - return - } - - // @todo allow overwrite - // 1. Check if asset already exists - if (fs.existsSync(`${publicFolderPath}/favicon.ico`)) { - console.info('Favicon: Assets already exist') - return - } - - // 2. Fetch theme and master asset url from site taxonomy - const siteTaxonomyRes = await fetch( - `${args.baseUrl}/api/v1/taxonomy_term/sites?filter%5Bdrupal_internal__tid%5D=${args.siteId}&site=${args.siteId}&include=field_site_favicon`, - { - method: 'GET', - credentials: 'same-origin', - headers: { - 'Content-Type': 'text/plain', - Authorization: 'Basic ' + Buffer.from('dpc:sdp').toString('base64') - } - } - ), - siteTaxonomyData = await siteTaxonomyRes.json(), - parsedData = jsonapiParse.parse(siteTaxonomyData).data[0] - - // 3. Extract site name - const siteName = - parsedData.field_site_slogan.processed.replace(/

|<\/p>/g, '') || - parsedData.name || - 'SDP' - - // 4. Extract theme colour (use Vic primary if theme is not set) - const themeColour = - parsedData.field_site_theme_values?.filter( - (t: any) => t.key.trim() === 'rpl-clr-primary' - )[0]?.value || '#0052C2' - - // 5. Set up master asset in public - const masterAssetUrl = parsedData.field_site_favicon?.url - if (!masterAssetUrl) { - console.info('Favicon: Master asset not set in site taxonomy') - return - } - - // 6. Create public folder if it doesn't exist at the app level - if (!fs.existsSync(publicFolderPath)) { - await fs.promises.mkdir(publicFolderPath) - } - - // 7. Fetch master asset - const savedFaviconPath = `${publicFolderPath}/${path.basename( - masterAssetUrl - )}` - - if (!fs.existsSync(savedFaviconPath)) { - const masterAssetRes = await fetch(masterAssetUrl), - fileStream = fs.createWriteStream(savedFaviconPath, { flags: 'wx' }) - // @ts-ignore TS2345 - await finished(Readable.fromWeb(masterAssetRes.body).pipe(fileStream)) - } - - // 8. Generate assets - await generate({ - masterPath: savedFaviconPath, - outputPath: publicFolderPath, - API_KEY: args.apiKey, - themeColour: themeColour, - siteName: siteName - }).then(() => { - // 9. Remove master asset - fs.unlinkSync(savedFaviconPath) - }) -} diff --git a/packages/nuxt-ripple-cli/src/commands/favicon/index.ts b/packages/nuxt-ripple-cli/src/commands/favicon/index.ts deleted file mode 100644 index 7445b4d0fa..0000000000 --- a/packages/nuxt-ripple-cli/src/commands/favicon/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -import commander from 'commander' -import favicon from './favicon' - -export default function rplFaviconCommand() { - const rplFaviconCommand = new commander.Command('favicon') - - rplFaviconCommand - .description('Generate favicon assets') - .option( - '-a, --apiKey ', - 'API key for the RealFaviconGenerator service' - ) - .option('-b, --baseUrl ', 'Tide API base url') - .option('-i, --siteId ', 'Tide site ID') - .option( - '-p, --publicPath ', - 'Absolute path to public directory', - `${process.cwd()}/public` - ) - .action(() => favicon(rplFaviconCommand.opts())) - - return rplFaviconCommand -} diff --git a/packages/nuxt-ripple-cli/src/commands/favicon/lib.d.ts b/packages/nuxt-ripple-cli/src/commands/favicon/lib.d.ts deleted file mode 100644 index bf3ecad64c..0000000000 --- a/packages/nuxt-ripple-cli/src/commands/favicon/lib.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare module 'rfg-api' -declare module 'jsonapi-parse' diff --git a/packages/nuxt-ripple-cli/src/commands/index.ts b/packages/nuxt-ripple-cli/src/commands/index.ts index 389f9b5b34..85deccbdf2 100644 --- a/packages/nuxt-ripple-cli/src/commands/index.ts +++ b/packages/nuxt-ripple-cli/src/commands/index.ts @@ -3,7 +3,6 @@ import commander from 'commander' import rplMockCommand from './mock' import rplInitCommand from './init' import rplAddCommand from './add' -import rplFaviconCommand from './favicon' const program = new commander.Command('ripple') @@ -15,7 +14,6 @@ const rippleCli = program rippleCli.addCommand(rplMockCommand()) rippleCli.addCommand(rplInitCommand()) rippleCli.addCommand(rplAddCommand()) -rippleCli.addCommand(rplFaviconCommand()) // TODO Add update command for existing sites program.parse(process.argv) diff --git a/packages/nuxt-ripple-preview/package.json b/packages/nuxt-ripple-preview/package.json index ba28ef4732..ddb6d15007 100644 --- a/packages/nuxt-ripple-preview/package.json +++ b/packages/nuxt-ripple-preview/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/nuxt-ripple-preview", "description": "Adds support for drupal preview links in Ripple frontend sites", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "main": "./nuxt.config.ts", "repository": "https://github.com/dpc-sdp/ripple-framework", diff --git a/packages/nuxt-ripple/mapping/base/index.ts b/packages/nuxt-ripple/mapping/base/index.ts index d180578407..6aac94e832 100644 --- a/packages/nuxt-ripple/mapping/base/index.ts +++ b/packages/nuxt-ripple/mapping/base/index.ts @@ -1,5 +1,7 @@ import { map as topicTagsMapping, + tagMap as tagMapping, + topicMap as topicMapping, includes as topicTagsIncludes } from './topic-tags/topic-tags-mapping.js' import { @@ -68,6 +70,8 @@ export const tidePageBaseMapping = ({ sidebar: sidebar, status: 'moderation_state', topicTags: topicTagsMapping, + tags: (src) => tagMapping(src?.field_tags), + topic: (src) => topicMapping(src?.field_topic), siteSection: async (src) => { // With the correct site/section id, we can now choose the correct site data from 'field_node_site' const siteData = getSiteSection(src._sectionId, src) @@ -83,7 +87,6 @@ export const tidePageBaseMapping = ({ showQuickExit: getBoolFromString( siteData?.field_show_exit_site_specific ), - theme: getSiteKeyValues('field_site_theme_values', siteData) || {}, featureFlags: getSiteKeyValues('field_site_feature_flags', siteData) || {} } diff --git a/packages/nuxt-ripple/mapping/base/topic-tags/__test__/rawdata.ts b/packages/nuxt-ripple/mapping/base/topic-tags/__test__/rawdata.ts new file mode 100644 index 0000000000..49135c874a --- /dev/null +++ b/packages/nuxt-ripple/mapping/base/topic-tags/__test__/rawdata.ts @@ -0,0 +1,903 @@ +/** + * This fixture was generated from this reference page: + * https://develop.reference.sdp.vic.gov.au/rpl2test-sidebar-related-links + * + * The api call to get this data was: + * https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/1de5a395-bc1b-4bdd-a0c8-9dab428abecf?site=8888&include=field_related_links + * + * Extra (empty) relationship and includes fields were removed for simplicity + */ + +// eslint-disable-next-line +export const rawData = { + jsonapi: { + version: '1.0', + meta: { links: { self: { href: 'http://jsonapi.org/format/1.0/' } } } + }, + data: { + type: 'node--landing_page', + id: '54e48008-bfe2-4770-9be9-8fa44f6fb1af', + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af?resourceVersion=id%3A574' + } + }, + attributes: { + drupal_internal__nid: 464, + drupal_internal__vid: 574, + langcode: 'en', + revision_timestamp: '2024-11-18T06:09:06+00:00', + revision_log: null, + status: true, + title: 'Topic and tags', + created: '2024-11-18T16:44:58+11:00', + changed: '2024-11-18T17:09:06+11:00', + promote: true, + sticky: false, + default_langcode: true, + revision_translation_affected: true, + moderation_state: 'published', + metatag: [ + { + tag: 'meta', + attributes: { + name: 'title', + content: + 'Topic and tags | Single Digital Presence Content Management System' + } + }, + { + tag: 'link', + attributes: { + rel: 'canonical', + href: 'https://develop.content.reference.sdp.vic.gov.au/test-tt' + } + }, + { tag: 'meta', attributes: { property: 'og:locale', content: 'en-AU' } } + ], + path: { + alias: '/test-tt', + pid: 3286, + langcode: 'en', + url: '/test-tt', + origin_alias: '/site-8888/test-tt', + origin_url: '/test-tt' + }, + field_landing_page_bg_colour: 'white', + field_landing_page_hero_theme: null, + field_landing_page_intro_text: null, + field_landing_page_nav_title: 'Site-section Navigation', + field_landing_page_show_contact: false, + field_landing_page_summary: '..', + field_metatags: null, + field_node_display_headings: 'showH2', + field_show_ack_of_country: false, + field_show_content_rating: true, + field_show_c_primary_caption: false, + field_show_hero_image_caption: false, + field_show_related_content: false, + field_show_site_section_nav: false, + field_show_social_sharing: true, + field_show_table_of_content: false, + field_show_topic_term_and_tags: true, + field_show_whats_next: false + }, + relationships: { + node_type: { + data: { + type: 'node_type--node_type', + id: '1f020dbf-3dd1-4f0f-8d83-0dbfb20d017d', + meta: { drupal_internal__target_id: 'landing_page' } + }, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/node_type?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/node_type?resourceVersion=id%3A574' + } + } + }, + revision_uid: { + data: null, + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/revision_uid?resourceVersion=id%3A574' + } + } + }, + uid: { + data: null, + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/uid?resourceVersion=id%3A574' + } + } + }, + field_bottom_graphical_image: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_bottom_graphical_image?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_bottom_graphical_image?resourceVersion=id%3A574' + } + } + }, + field_content_category: { + data: [ + { + type: 'taxonomy_term--content_category', + id: '0a99de42-2a84-4a9d-90a5-a82dd0a20f7a', + meta: { drupal_internal__target_id: 9147 } + } + ], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_content_category?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_content_category?resourceVersion=id%3A574' + } + } + }, + field_featured_image: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_featured_image?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_featured_image?resourceVersion=id%3A574' + } + } + }, + field_graphical_image: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_graphical_image?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_graphical_image?resourceVersion=id%3A574' + } + } + }, + field_landing_page_component: { + data: [], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_landing_page_component?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_landing_page_component?resourceVersion=id%3A574' + } + } + }, + field_landing_page_contact: { + data: [], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_landing_page_contact?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_landing_page_contact?resourceVersion=id%3A574' + } + } + }, + field_landing_page_c_primary: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_landing_page_c_primary?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_landing_page_c_primary?resourceVersion=id%3A574' + } + } + }, + field_landing_page_c_secondary: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_landing_page_c_secondary?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_landing_page_c_secondary?resourceVersion=id%3A574' + } + } + }, + field_landing_page_header: { + data: [], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_landing_page_header?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_landing_page_header?resourceVersion=id%3A574' + } + } + }, + field_landing_page_hero_banner: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_landing_page_hero_banner?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_landing_page_hero_banner?resourceVersion=id%3A574' + } + } + }, + field_landing_page_hero_image: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_landing_page_hero_image?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_landing_page_hero_image?resourceVersion=id%3A574' + } + } + }, + field_landing_page_hero_logo: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_landing_page_hero_logo?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_landing_page_hero_logo?resourceVersion=id%3A574' + } + } + }, + field_landing_page_key_journeys: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_landing_page_key_journeys?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_landing_page_key_journeys?resourceVersion=id%3A574' + } + } + }, + field_node_primary_site: { + data: { + type: 'taxonomy_term--sites', + id: '11dede11-10c0-111e1-1100-000000000040', + meta: { drupal_internal__target_id: 8888 } + }, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_node_primary_site?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_node_primary_site?resourceVersion=id%3A574' + } + } + }, + field_node_site: { + data: [ + { + type: 'taxonomy_term--sites', + id: '11dede11-10c0-111e1-1100-000000000040', + meta: { drupal_internal__target_id: 8888 } + } + ], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_node_site?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_node_site?resourceVersion=id%3A574' + } + } + }, + field_related_links: { + data: [], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_related_links?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_related_links?resourceVersion=id%3A574' + } + } + }, + field_tags: { + data: [ + { + type: 'taxonomy_term--tags', + id: '11dede11-10c0-111e1-1101-000000000010', + meta: { drupal_internal__target_id: 9180 } + }, + { + type: 'taxonomy_term--tags', + id: '11dede11-10c0-111e1-1101-000000000011', + meta: { drupal_internal__target_id: 9181 } + } + ], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_tags?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_tags?resourceVersion=id%3A574' + } + } + }, + field_topic: { + data: { + type: 'taxonomy_term--topic', + id: '11dede11-10c0-111e1-1102-000000000020', + meta: { drupal_internal__target_id: 9192 } + }, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_topic?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_topic?resourceVersion=id%3A574' + } + } + }, + field_whats_next: { + data: [], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/field_whats_next?resourceVersion=id%3A574' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af/relationships/field_whats_next?resourceVersion=id%3A574' + } + } + } + } + }, + included: [ + { + type: 'taxonomy_term--sites', + id: '11dede11-10c0-111e1-1100-000000000040', + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040?resourceVersion=id%3A342' + } + }, + attributes: { + drupal_internal__tid: 8888, + drupal_internal__revision_id: 342, + revision_created: '2024-11-17T11:17:39+00:00', + revision_log_message: null, + status: true, + name: 'Demo Site', + revision_translation_affected: true, + metatag: [ + { + tag: 'meta', + attributes: { + name: 'title', + content: + 'Demo Site | Single Digital Presence Content Management System' + } + }, + { + tag: 'link', + attributes: { + rel: 'canonical', + href: 'https://develop.content.reference.sdp.vic.gov.au/sites/demo-site' + } + }, + { + tag: 'meta', + attributes: { property: 'og:locale', content: 'en-AU' } + } + ], + field_acknowledgement_to_country: + 'The Victorian Government acknowledges Aboriginal and Torres Strait Islander people as the Traditional Custodians of the land and acknowledges and pays respect to their Elders, past and present.', + field_additional_comment: { + value: + '\u003Cp\u003E\u003Cspan\u003EIf you need a response, please use our \u003C/span\u003E\u003Ca class=\u0022rpl-text-link rpl-u-focusable-inline\u0022 href=\u0022https://www.vic.gov.au/contact-us\u0022\u003Econtact us form\u003C/a\u003E\u003Cspan\u003E.\u003C/span\u003E\u003C/p\u003E', + format: 'rich_text', + processed: + '\u003Cp\u003E\u003Cspan\u003EIf you need a response, please use our \u003C/span\u003E\u003Ca class=\u0022rpl-text-link rpl-u-focusable-inline\u0022 href=\u0022https://www.vic.gov.au/contact-us\u0022\u003Econtact us form\u003C/a\u003E\u003Cspan\u003E.\u003C/span\u003E\u003C/p\u003E' + }, + field_prominence_ack_to_country: null, + field_show_table_of_contents: true, + field_site_domains: 'www.demo.vic.gov.au', + field_site_feature_flags: [], + field_site_footer_text: null, + field_site_show_exit_site: false, + field_site_slogan: null, + field_site_social_links: [], + field_site_theme_values: [], + field_title_of_table_of_contents: 'Jump to' + }, + relationships: { + revision_user: { + data: null, + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/revision_user?resourceVersion=id%3A342' + } + } + }, + field_bottom_corner_graphic: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_bottom_corner_graphic?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_bottom_corner_graphic?resourceVersion=id%3A342' + } + } + }, + field_print_friendly_logo: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_print_friendly_logo?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_print_friendly_logo?resourceVersion=id%3A342' + } + } + }, + field_site_favicon: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_site_favicon?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_site_favicon?resourceVersion=id%3A342' + } + } + }, + field_site_footer_logos: { + data: [], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_site_footer_logos?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_site_footer_logos?resourceVersion=id%3A342' + } + } + }, + field_site_footer_menu: { + data: { + type: 'menu--menu', + id: '78fd1a92-e20e-4639-9396-a1b7ed73b8d4', + meta: { drupal_internal__target_id: 'footer-tide-demo' } + }, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_site_footer_menu?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_site_footer_menu?resourceVersion=id%3A342' + } + } + }, + field_site_homepage: { + data: { + type: 'node--landing_page', + id: '11dede11-10c0-111e1-1100-000000000330', + meta: { drupal_internal__target_id: 184 } + }, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_site_homepage?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_site_homepage?resourceVersion=id%3A342' + } + } + }, + field_site_logo: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_site_logo?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_site_logo?resourceVersion=id%3A342' + } + } + }, + field_site_main_menu: { + data: { + type: 'menu--menu', + id: '565a73f0-60ca-4340-9f21-2dee79179270', + meta: { drupal_internal__target_id: 'main-tide-demo' } + }, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_site_main_menu?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_site_main_menu?resourceVersion=id%3A342' + } + } + }, + field_site_og_image: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_site_og_image?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_site_og_image?resourceVersion=id%3A342' + } + } + }, + field_site_twitter_image: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_site_twitter_image?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_site_twitter_image?resourceVersion=id%3A342' + } + } + }, + field_top_corner_graphic: { + data: null, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/field_top_corner_graphic?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/field_top_corner_graphic?resourceVersion=id%3A342' + } + } + }, + site_alerts: { + data: [ + { + type: 'node--alert', + id: '11dede11-10c0-111e1-1100-000000000350', + meta: { drupal_internal__target_id: 201 } + }, + { + type: 'node--alert', + id: '08aaff50-d5d3-4d05-8932-0e1d723a218e', + meta: { drupal_internal__target_id: 199 } + }, + { + type: 'node--alert', + id: '587d6ee7-8bbf-4f6a-954d-a4e63a530159', + meta: { drupal_internal__target_id: 200 } + } + ], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/site_alerts?resourceVersion=id%3A342' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/sites/11dede11-10c0-111e1-1100-000000000040/relationships/site_alerts?resourceVersion=id%3A342' + } + } + } + } + }, + { + type: 'menu--menu', + id: '565a73f0-60ca-4340-9f21-2dee79179270', + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/menu/menu/565a73f0-60ca-4340-9f21-2dee79179270' + } + }, + attributes: { + langcode: 'en', + status: true, + dependencies: [], + drupal_internal__id: 'main-tide-demo', + label: 'Main menu - demo.vic.gov.au', + description: 'Demo main menu', + locked: false + } + }, + { + type: 'taxonomy_term--tags', + id: '11dede11-10c0-111e1-1101-000000000010', + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000010?resourceVersion=id%3A319' + } + }, + attributes: { + drupal_internal__tid: 9180, + drupal_internal__revision_id: 319, + langcode: 'en', + revision_created: '2024-11-17T11:17:39+00:00', + revision_log_message: null, + status: true, + name: 'Demo Tag', + description: null, + weight: 0, + changed: '2024-11-17T11:17:39+00:00', + default_langcode: true, + revision_translation_affected: true, + metatag: [ + { + tag: 'meta', + attributes: { + name: 'title', + content: + 'Demo Tag | Single Digital Presence Content Management System' + } + }, + { + tag: 'link', + attributes: { + rel: 'canonical', + href: 'https://develop.content.reference.sdp.vic.gov.au/tags/demo-tag' + } + }, + { + tag: 'meta', + attributes: { property: 'og:locale', content: 'en-AU' } + } + ], + path: { alias: '/tags/demo-tag', pid: 1000, langcode: 'en' } + }, + relationships: { + vid: { + data: { + type: 'taxonomy_vocabulary--taxonomy_vocabulary', + id: '41649943-5bfa-4c01-a10a-683e2bc83ded', + meta: { drupal_internal__target_id: 'tags' } + }, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000010/vid?resourceVersion=id%3A319' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000010/relationships/vid?resourceVersion=id%3A319' + } + } + }, + revision_user: { + data: null, + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000010/relationships/revision_user?resourceVersion=id%3A319' + } + } + }, + parent: { + data: [ + { + type: 'taxonomy_term--tags', + id: 'virtual', + meta: { + links: { + help: { + href: 'https://www.drupal.org/docs/8/modules/json-api/core-concepts#virtual', + meta: { + about: + 'Usage and meaning of the \u0027virtual\u0027 resource identifier.' + } + } + } + } + } + ], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000010/parent?resourceVersion=id%3A319' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000010/relationships/parent?resourceVersion=id%3A319' + } + } + } + } + }, + { + type: 'taxonomy_term--tags', + id: '11dede11-10c0-111e1-1101-000000000011', + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000011?resourceVersion=id%3A320' + } + }, + attributes: { + drupal_internal__tid: 9181, + drupal_internal__revision_id: 320, + langcode: 'en', + revision_created: '2024-11-17T11:17:39+00:00', + revision_log_message: null, + status: true, + name: 'Another Demo Tag', + description: null, + weight: 0, + changed: '2024-11-17T11:17:39+00:00', + default_langcode: true, + revision_translation_affected: true, + metatag: [ + { + tag: 'meta', + attributes: { + name: 'title', + content: + 'Another Demo Tag | Single Digital Presence Content Management System' + } + }, + { + tag: 'link', + attributes: { + rel: 'canonical', + href: 'https://develop.content.reference.sdp.vic.gov.au/tags/another-demo-tag' + } + }, + { + tag: 'meta', + attributes: { property: 'og:locale', content: 'en-AU' } + } + ], + path: { alias: '/tags/another-demo-tag', pid: 1001, langcode: 'en' } + }, + relationships: { + vid: { + data: { + type: 'taxonomy_vocabulary--taxonomy_vocabulary', + id: '41649943-5bfa-4c01-a10a-683e2bc83ded', + meta: { drupal_internal__target_id: 'tags' } + }, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000011/vid?resourceVersion=id%3A320' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000011/relationships/vid?resourceVersion=id%3A320' + } + } + }, + revision_user: { + data: null, + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000011/relationships/revision_user?resourceVersion=id%3A320' + } + } + }, + parent: { + data: [ + { + type: 'taxonomy_term--tags', + id: 'virtual', + meta: { + links: { + help: { + href: 'https://www.drupal.org/docs/8/modules/json-api/core-concepts#virtual', + meta: { + about: + 'Usage and meaning of the \u0027virtual\u0027 resource identifier.' + } + } + } + } + } + ], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000011/parent?resourceVersion=id%3A320' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/tags/11dede11-10c0-111e1-1101-000000000011/relationships/parent?resourceVersion=id%3A320' + } + } + } + } + }, + { + type: 'taxonomy_term--topic', + id: '11dede11-10c0-111e1-1102-000000000020', + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/topic/11dede11-10c0-111e1-1102-000000000020?resourceVersion=id%3A331' + } + }, + attributes: { + drupal_internal__tid: 9192, + drupal_internal__revision_id: 331, + langcode: 'en', + revision_created: '2024-11-17T11:17:39+00:00', + revision_log_message: null, + status: true, + name: 'Demo Topic', + description: null, + weight: 0, + changed: '2024-11-17T11:17:39+00:00', + default_langcode: true, + revision_translation_affected: true, + metatag: [ + { + tag: 'meta', + attributes: { + name: 'title', + content: + 'Demo Topic | Single Digital Presence Content Management System' + } + }, + { + tag: 'link', + attributes: { + rel: 'canonical', + href: 'https://develop.content.reference.sdp.vic.gov.au/topic/demo-topic' + } + }, + { + tag: 'meta', + attributes: { property: 'og:locale', content: 'en-AU' } + } + ], + path: { alias: '/topic/demo-topic', pid: 1012, langcode: 'en' } + }, + relationships: { + vid: { + data: { + type: 'taxonomy_vocabulary--taxonomy_vocabulary', + id: '4b949eaa-401e-48a0-802f-da2496743e6d', + meta: { drupal_internal__target_id: 'topic' } + }, + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/topic/11dede11-10c0-111e1-1102-000000000020/vid?resourceVersion=id%3A331' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/topic/11dede11-10c0-111e1-1102-000000000020/relationships/vid?resourceVersion=id%3A331' + } + } + }, + revision_user: { + data: null, + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/topic/11dede11-10c0-111e1-1102-000000000020/relationships/revision_user?resourceVersion=id%3A331' + } + } + }, + parent: { + data: [ + { + type: 'taxonomy_term--topic', + id: 'virtual', + meta: { + links: { + help: { + href: 'https://www.drupal.org/docs/8/modules/json-api/core-concepts#virtual', + meta: { + about: + 'Usage and meaning of the \u0027virtual\u0027 resource identifier.' + } + } + } + } + } + ], + links: { + related: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/topic/11dede11-10c0-111e1-1102-000000000020/parent?resourceVersion=id%3A331' + }, + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/taxonomy_term/topic/11dede11-10c0-111e1-1102-000000000020/relationships/parent?resourceVersion=id%3A331' + } + } + } + } + } + ], + links: { + self: { + href: 'https://develop.content.reference.sdp.vic.gov.au/api/v1/node/landing_page/54e48008-bfe2-4770-9be9-8fa44f6fb1af?include=field_node_site%2Cfield_tags%2Cfield_topic%2Cfield_landing_page_contact%2Cfield_landing_page_contact.field_paragraph_phones%2Cfield_landing_page_contact.field_paragraph_social_media%2Cfield_related_links%2Cfield_whats_next%2Cfield_node_site.field_site_main_menu%2Cfield_landing_page_hero_banner%2Cfield_landing_page_key_journeys%2Cfield_landing_page_hero_logo.field_media_image%2Cfield_landing_page_hero_image.field_media_image%2Cfield_graphical_image.field_media_image%2Cfield_bottom_graphical_image.field_media_image%2Cfield_landing_page_c_primary.field_block_image.field_media_image%2Cfield_landing_page_c_secondary.field_block_image.field_media_image%2Cfield_landing_page_header%2Cfield_landing_page_component.field_paragraph_media.field_media_image%2Cfield_landing_page_component.field_paragraph_topic%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_reference.field_event_details%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_reference.field_topic%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_reference.field_featured_image.field_media_image%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_keydates%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_media.field_media_image%2Cfield_landing_page_component.field_paragraph_accordion%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_paragraph_accordion%2Cfield_landing_page_component.field_paragraph_keydates%2Cfield_landing_page_component.field_statistic_block%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_statistic_block%2Cfield_landing_page_component.field_timeline.field_paragraph_media.field_media_image%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_timeline.field_paragraph_media.field_media_image%2Cfield_landing_page_component.field_paragraph_media_gallery.field_gallery_media.field_media_image%2Cfield_landing_page_component.field_paragraph_media_gallery.field_gallery_media.field_media_image%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_reference.field_event_details%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_reference.field_topic%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_reference.field_featured_image.field_media_image%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_keydates%2Cfield_landing_page_component.field_paragraph_items.field_paragraph_media.field_media_image%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_paragraph_media_gallery.field_gallery_media.field_media_image%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_paragraph_items.field_paragraph_reference.field_event_details%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_paragraph_items.field_paragraph_reference.field_topic%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_paragraph_items.field_paragraph_reference.field_featured_image.field_media_image%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_paragraph_items.field_paragraph_keydates%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_paragraph_items.field_paragraph_media.field_media_image%2Cfield_landing_page_component.field_paragraph_webform%2Cfield_landing_page_component.field_complex_image_media.field_media_image%2Cfield_landing_page_component.field_reusable_paragraph.paragraphs.field_complex_image_media.field_media_image%2Cfield_landing_page_component.field_compact_card%2Cfield_landing_page_component.field_compact_card.field_paragraph_media.field_media_image\u0026site=8888' + } + } +} diff --git a/packages/nuxt-ripple/mapping/base/topic-tags/__test__/topic-tags-mapping.test.ts b/packages/nuxt-ripple/mapping/base/topic-tags/__test__/topic-tags-mapping.test.ts new file mode 100644 index 0000000000..9a894d5fdb --- /dev/null +++ b/packages/nuxt-ripple/mapping/base/topic-tags/__test__/topic-tags-mapping.test.ts @@ -0,0 +1,35 @@ +import { expect, describe, it, beforeAll } from '@jest/globals' +import * as jsonapiParse from 'jsonapi-parse' +import { rawData } from './rawdata' +import { + map as topicTagMapping, + tagMap as tagMapping, + topicMap as topicMapping +} from '../topic-tags-mapping' + +const topicResult = { text: 'Demo Topic', url: '/topic/demo-topic' } + +const tagsResult = [ + { text: 'Demo Tag', url: '/tags/demo-tag' }, + { text: 'Another Demo Tag', url: '/tags/another-demo-tag' } +] + +describe('sidebarWhatsNextMapping', () => { + let parsedData + + beforeAll(() => { + parsedData = jsonapiParse.parse(rawData).data + }) + + it('maps a raw json api response to a single topic', () => { + expect(topicMapping(parsedData.field_topic)).toEqual(topicResult) + }) + + it('maps a raw json api response to an array of tags', () => { + expect(tagMapping(parsedData.field_tags)).toEqual(tagsResult) + }) + + it('maps a raw json api response to an array of topic and tags', () => { + expect(topicTagMapping(parsedData)).toEqual([topicResult, ...tagsResult]) + }) +}) diff --git a/packages/nuxt-ripple/mapping/base/topic-tags/topic-tags-mapping.ts b/packages/nuxt-ripple/mapping/base/topic-tags/topic-tags-mapping.ts index b2e86deb26..e8da865dbb 100644 --- a/packages/nuxt-ripple/mapping/base/topic-tags/topic-tags-mapping.ts +++ b/packages/nuxt-ripple/mapping/base/topic-tags/topic-tags-mapping.ts @@ -5,17 +5,17 @@ export interface TideTopicTag { url: string } -export const map = (src: TideApiResponse): TideTopicTag[] => { - const topics: TideTopicTag[] = [] +export const topicMap = (topic: any): TideTopicTag | null => { + if (!topic?.name) return null - if (src.field_topic?.name) { - topics.push({ - text: src.field_topic.name, - url: src.field_topic.path?.alias || '' - }) + return { + text: topic.name, + url: topic.path?.alias || '' } +} - const tags = (src.field_tags || []) +export const tagMap = (tags: any): TideTopicTag[] => { + return (tags || []) .map((rawTag: any) => { if (!rawTag?.name) return null @@ -25,8 +25,13 @@ export const map = (src: TideApiResponse): TideTopicTag[] => { } }) .filter(Boolean) +} + +export const map = (src: TideApiResponse): TideTopicTag[] => { + const topic = topicMap(src?.field_topic) + const tags = tagMap(src?.field_tags) - return [...topics, ...tags] + return topic ? [topic, ...tags] : tags } export const includes = ['field_tags', 'field_topic'] diff --git a/packages/nuxt-ripple/package.json b/packages/nuxt-ripple/package.json index f956a935a6..362ea124a0 100644 --- a/packages/nuxt-ripple/package.json +++ b/packages/nuxt-ripple/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/nuxt-ripple", "description": "Nuxt module for integrating Ripple and Tide", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "main": "./nuxt.config.ts", "repository": "https://github.com/dpc-sdp/ripple-framework", diff --git a/packages/ripple-sdp-core/package.json b/packages/ripple-sdp-core/package.json index 20caf759dc..bf57928463 100644 --- a/packages/ripple-sdp-core/package.json +++ b/packages/ripple-sdp-core/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-sdp-core", "description": "SDP core content types", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "./nuxt.config.ts", diff --git a/packages/ripple-storybook/package.json b/packages/ripple-storybook/package.json index 949b8c3679..56ea4d9646 100644 --- a/packages/ripple-storybook/package.json +++ b/packages/ripple-storybook/package.json @@ -1,7 +1,7 @@ { "name": "ripple-storybook", "description": "Ripple Storybook instance", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "private": true, "repository": "https://github.com/dpc-sdp/ripple-framework", diff --git a/packages/ripple-test-utils/package.json b/packages/ripple-test-utils/package.json index e416e4bbdc..7ad8db07f0 100644 --- a/packages/ripple-test-utils/package.json +++ b/packages/ripple-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-test-utils", "description": "Test utils for Ripple sites", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "type": "module", "main": "./dist/config/index.js", diff --git a/packages/ripple-test-utils/step_definitions/common/site/analytics.ts b/packages/ripple-test-utils/step_definitions/common/site/analytics.ts index 898852e4dc..817a791a9a 100644 --- a/packages/ripple-test-utils/step_definitions/common/site/analytics.ts +++ b/packages/ripple-test-utils/step_definitions/common/site/analytics.ts @@ -68,6 +68,18 @@ Then( } ) +Then('the dataLayer should have the following tags', (dataTable: DataTable) => { + const table = dataTable.hashes() + + cy.window().then((window) => { + const event = window.dataLayer?.find((i) => i.event === 'routeChange') + + table.forEach((row, index) => { + expect(event?.content_tags[index]).to.contain(row.name) + }) + }) +}) + Then( 'the dataLayer form data for {string} should include the following values', (name: string, dataTable: DataTable) => { diff --git a/packages/ripple-test-utils/step_definitions/components/custom-collection.ts b/packages/ripple-test-utils/step_definitions/components/custom-collection.ts index 5e5aef64ae..fce47877df 100644 --- a/packages/ripple-test-utils/step_definitions/components/custom-collection.ts +++ b/packages/ripple-test-utils/step_definitions/components/custom-collection.ts @@ -15,6 +15,10 @@ Then( } ) +When(`I type {string} into the custom collection input`, (inputStr: string) => { + cy.get(`[id="custom-collection-search-bar"]`).type(`${inputStr}`) +}) + Then(`the custom collection component results count should be hidden`, () => { cy.get(`[data-component-type="search-listing-result-count"]`).should( 'not.exist' @@ -118,14 +122,15 @@ Then( When(`I toggle the content collection filters`, () => { cy.get(`[data-component-type="TideCustomCollection"]`) .find(`button`) - .contains('Refine search') + .contains('Filters') .click() }) Then( 'the custom collection config has {string} set to {string}', - (key: string, value: string | boolean) => { + (key: string, value: string | boolean | number) => { cy.get('@pageFixture').then((response) => { + if (!isNaN(Number(value))) value = Number(value) if (value === 'true') value = true if (value === 'false') value = false set(response, `bodyComponents[0].props.searchListingConfig.${key}`, value) diff --git a/packages/ripple-test-utils/step_definitions/components/maps.ts b/packages/ripple-test-utils/step_definitions/components/maps.ts index 51c4276544..aa1a08e850 100644 --- a/packages/ripple-test-utils/step_definitions/components/maps.ts +++ b/packages/ripple-test-utils/step_definitions/components/maps.ts @@ -287,3 +287,7 @@ Given('the map height is set to {int}', (height: number) => { Then('the map height is {int}', (height: number) => { cy.get('.rpl-map__map').should('have.css', 'height', `${height}px`) }) + +Then('the map is loaded', () => { + cy.get('.ol-map-fully-loaded', { timeout: 12000 }).should('be.visible') +}) diff --git a/packages/ripple-test-utils/step_definitions/content-types/listing.ts b/packages/ripple-test-utils/step_definitions/content-types/listing.ts index 5345e354b2..920157ec48 100644 --- a/packages/ripple-test-utils/step_definitions/content-types/listing.ts +++ b/packages/ripple-test-utils/step_definitions/content-types/listing.ts @@ -356,7 +356,7 @@ Then( ) When(`I toggle the search listing filters section`, () => { - cy.get(`button`).contains('Refine search').as('refineBtn') + cy.get(`button`).contains('Filters').as('refineBtn') cy.wait(300) cy.get('@refineBtn').click() }) @@ -374,15 +374,15 @@ Then( (filterCount: number) => { if (filterCount === 0) { cy.get(`button`) - .contains('Refine search') + .contains('Filters') .should(($div) => { - expect($div.text().trim()).equal(`Refine search`) + expect($div.text().trim()).equal(`Filters`) }) } else { cy.get(`button`) - .contains('Refine search') + .contains('Filters') .should(($div) => { - expect($div.text().trim()).equal(`Refine search (${filterCount})`) + expect($div.text().trim()).equal(`Filters (${filterCount})`) }) } } @@ -507,6 +507,10 @@ When('I click the search suggestion labelled {string}', (label: string) => { .click() }) +Then('the search suggestions should be displayed', () => { + cy.get('#tide-search-bar__menu').should('exist') +}) + Then('the search suggestions should not be displayed', () => { cy.get('#tide-search-bar__menu').should('not.exist') }) diff --git a/packages/ripple-tide-api/package.json b/packages/ripple-tide-api/package.json index f32bd904eb..e605076b6d 100644 --- a/packages/ripple-tide-api/package.json +++ b/packages/ripple-tide-api/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-tide-api", "description": "Ripple API endpoints for Tide Drupal backend", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "./dist/index.js", diff --git a/packages/ripple-tide-api/src/utils/markup-transpiler/cheerio.test.ts b/packages/ripple-tide-api/src/utils/markup-transpiler/cheerio.test.ts index f21e09156c..bf2c3be282 100644 --- a/packages/ripple-tide-api/src/utils/markup-transpiler/cheerio.test.ts +++ b/packages/ripple-tide-api/src/utils/markup-transpiler/cheerio.test.ts @@ -3,6 +3,7 @@ import markupTranspiler from './index' const markup = { table: ` + @@ -26,6 +27,7 @@ const markup = { const fixed = { table: `
FnameLname
JoeCool
+ diff --git a/packages/ripple-tide-api/src/utils/markup-transpiler/default-plugins.ts b/packages/ripple-tide-api/src/utils/markup-transpiler/default-plugins.ts index 7f8431db8a..0726c18715 100644 --- a/packages/ripple-tide-api/src/utils/markup-transpiler/default-plugins.ts +++ b/packages/ripple-tide-api/src/utils/markup-transpiler/default-plugins.ts @@ -5,6 +5,16 @@ const pluginTables = function (this: any) { // Wrap tables with a div. this.find('table').map((i: any, el: any) => { const $table = this.find(el) + + $table.find('col[data-width]').each((i: any, col: any) => { + const $col = this.find(col) + const colWidth = $col.attr('data-width') + + if (colWidth) { + $col.attr('style', `width: ${colWidth}`).removeAttr('data-width') + } + }) + return $table .wrap(`
`) .wrap( diff --git a/packages/ripple-tide-api/types.d.ts b/packages/ripple-tide-api/types.d.ts index d26f7efcdb..2dccef88ee 100644 --- a/packages/ripple-tide-api/types.d.ts +++ b/packages/ripple-tide-api/types.d.ts @@ -141,7 +141,6 @@ export type TidePropRange = { export type TideSiteSectionOverrides = { showQuickExit: boolean - theme: Record featureFlags: IRplFeatureFlags } diff --git a/packages/ripple-tide-event/package.json b/packages/ripple-tide-event/package.json index 7e0567ed40..97715519e1 100644 --- a/packages/ripple-tide-event/package.json +++ b/packages/ripple-tide-event/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-tide-event", "description": "Ripple mappings and components for Tide Event Content type", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "main": "./nuxt.config.ts", "repository": "https://github.com/dpc-sdp/ripple-framework", diff --git a/packages/ripple-tide-grant/package.json b/packages/ripple-tide-grant/package.json index f31e8e5092..7a21d83488 100644 --- a/packages/ripple-tide-grant/package.json +++ b/packages/ripple-tide-grant/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-tide-grant", "description": "Ripple mappings and components for Tide Grant Content type", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "./nuxt.config.ts", diff --git a/packages/ripple-tide-landing-page/package.json b/packages/ripple-tide-landing-page/package.json index 908456876b..93a19b312e 100644 --- a/packages/ripple-tide-landing-page/package.json +++ b/packages/ripple-tide-landing-page/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-tide-landing-page", "description": "Ripple mappings and components for Tide landing-page Content type", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "./nuxt.config.ts", diff --git a/packages/ripple-tide-media/package.json b/packages/ripple-tide-media/package.json index 1bd2aaab6d..a7d1c9009e 100644 --- a/packages/ripple-tide-media/package.json +++ b/packages/ripple-tide-media/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-tide-media", "description": "Ripple mappings and components for Tide media", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "./nuxt.config.ts", diff --git a/packages/ripple-tide-news/package.json b/packages/ripple-tide-news/package.json index 05b183c81d..204d39e2d0 100644 --- a/packages/ripple-tide-news/package.json +++ b/packages/ripple-tide-news/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-tide-news", "description": "Ripple mappings and components for Tide News content type", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "./nuxt.config.ts", diff --git a/packages/ripple-tide-publication/package.json b/packages/ripple-tide-publication/package.json index 4de15143e3..c181fb9b51 100644 --- a/packages/ripple-tide-publication/package.json +++ b/packages/ripple-tide-publication/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-tide-publication", "description": "Ripple mappings and components for Tide Publication Content type", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "./nuxt.config.ts", diff --git a/packages/ripple-tide-search/components/TideSearchListingPage.vue b/packages/ripple-tide-search/components/TideSearchListingPage.vue index 9c43c28e1f..f706ea837f 100644 --- a/packages/ripple-tide-search/components/TideSearchListingPage.vue +++ b/packages/ripple-tide-search/components/TideSearchListingPage.vue @@ -30,8 +30,6 @@ interface Props { id?: string title: string introText?: string - autocompleteQuery?: boolean - autocompleteMinimumCharacters?: number searchListingConfig?: TideSearchListingConfig['searchListingConfig'] sortOptions?: TideSearchListingConfig['sortOptions'] customQueryConfig?: TideSearchListingConfig['customQueryConfig'] @@ -51,8 +49,6 @@ const props = withDefaults(defineProps(), { id: 'tide-search-listing', title: 'Search', introText: '', - autocompleteQuery: true, - autocompleteMinimumCharacters: 3, globalFilters: () => [], userFilters: () => [], customQueryConfig: undefined, @@ -280,11 +276,11 @@ const handleUpdateSearchTerm = (term: string) => { } const getDebouncedSuggestions = useDebounceFn((term: string) => { - if ( - props.autocompleteQuery && - props.searchListingConfig?.suggestions?.enabled !== false - ) { - if (term?.length >= props.autocompleteMinimumCharacters) { + if (props.searchListingConfig?.suggestions?.enabled) { + const minCharacters = + props.searchListingConfig?.suggestions?.minCharacters || 3 + + if (term?.length >= minCharacters) { getSuggestions() } else if (suggestions.value?.length) { clearSuggestions() @@ -336,7 +332,7 @@ const numAppliedFilters = computed(() => { }) const toggleFiltersLabel = computed(() => { - let label = 'Refine search' + let label = 'Filters' return numAppliedFilters.value ? `${label} (${numAppliedFilters.value})` @@ -423,7 +419,6 @@ watch( { :input-label="searchListingConfig.labels?.submit" :inputValue="searchTerm.q" :placeholder="searchListingConfig.labels?.placeholder" + :suggestions="suggestions" :global-events="false" :maxlength="128" @submit="handleSearchSubmit" @@ -619,7 +625,6 @@ const locationOrGeolocation = computed(() => {
{ + const raw = '2024-08-02T09:00:00+1000' + + it('formats a date', () => { + expect(formatDate(raw)).toEqual('2 Aug 2024') + }) + + it('accepts custom date options', () => { + expect( + formatDate(raw, { day: 'numeric', month: 'short', year: '2-digit' }) + ).toEqual('2 Aug 24') + }) + + it('accepts custom date options with a non-default tz', () => { + expect( + formatDate(raw, { + dateStyle: 'medium', + timeZone: 'Japan', + timeStyle: 'short' + }) + ).toEqual('2 Aug 2024, 8:00 am') + }) +}) + +describe('Transform distance to percentage', () => { + it('transforms a simple 100-scale', () => { + expect(distanceAsPercentage(35, 100)).toEqual(35) + }) + + it('transforms a point above ceil', () => { + expect(distanceAsPercentage(110, 100)).toEqual(100) + }) + + it('transforms a point below floor', () => { + expect(distanceAsPercentage(-80, 100)).toEqual(0) + }) + + it('transforms a complex scale', () => { + expect(distanceAsPercentage(29, 76)).toEqual(38.16) + }) +}) diff --git a/packages/ripple-ui-core/src/lib/helpers.ts b/packages/ripple-ui-core/src/lib/helpers.ts index 6e1338a666..22d6f2ca37 100644 --- a/packages/ripple-ui-core/src/lib/helpers.ts +++ b/packages/ripple-ui-core/src/lib/helpers.ts @@ -11,15 +11,24 @@ export const distanceAsPercentage = (point: number, total: number): number => { export const formatDate = ( value: string | number | Date, - options: Intl.DateTimeFormatOptions = {} + options: Intl.DateTimeFormatOptions | undefined = undefined ): string => { const date = new Date(value) - const defaultOptions: Intl.DateTimeFormatOptions = { dateStyle: 'medium', timeZone: 'Australia/Melbourne' } + const defaultOptions: Intl.DateTimeFormatOptions = { + dateStyle: 'medium', + timeZone: 'Australia/Melbourne' + } - options = { ...defaultOptions, ...options } + // Set default TZ + if (options && !options.timeZone) { + options.timeZone = 'Australia/Melbourne' + } - return new Intl.DateTimeFormat('en-AU', options).format(date) + return new Intl.DateTimeFormat( + 'en-AU', + options ? options : defaultOptions + ).format(date) } export { formatDateRange } from './formatDateRange' diff --git a/packages/ripple-ui-forms/package.json b/packages/ripple-ui-forms/package.json index 629ab4f751..a155b56162 100644 --- a/packages/ripple-ui-forms/package.json +++ b/packages/ripple-ui-forms/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-ui-forms", "description": "A form component library built with Formkit", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "main": "./dist/rpl-forms.umd.js", diff --git a/packages/ripple-ui-maps/package.json b/packages/ripple-ui-maps/package.json index b91a371964..4931a285fe 100644 --- a/packages/ripple-ui-maps/package.json +++ b/packages/ripple-ui-maps/package.json @@ -1,7 +1,7 @@ { "name": "@dpc-sdp/ripple-ui-maps", "description": "Ripple UI Core component library", - "version": "2.20.0", + "version": "2.21.0", "license": "Apache-2.0", "repository": "https://github.com/dpc-sdp/ripple-framework", "files": [ diff --git a/packages/ripple-ui-maps/src/components/map/RplMap.vue b/packages/ripple-ui-maps/src/components/map/RplMap.vue index d01f7d87da..bf6cd21cfe 100644 --- a/packages/ripple-ui-maps/src/components/map/RplMap.vue +++ b/packages/ripple-ui-maps/src/components/map/RplMap.vue @@ -1,7 +1,5 @@
FnameLname
JoeCool