diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 25e4336f5..a45be7524 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,5 @@ Fix # Test URLs: -- Before: https://main--vg-macktrucks-com-rd--netcentric.hlx.page/ -- After: https://--vg-macktrucks-com-rd--netcentric.hlx.page/ +- Before: https://main--vg-macktrucks-com--hlxsites.hlx.page/ +- After: https://--vg-macktrucks-com--hlxsites.hlx.page/ diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 000000000..6809eb9b5 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,22 @@ +# .github/release.yml + +changelog: + exclude: + labels: + - ignore-for-release + categories: + - title: Functional requirements + labels: + - FR + - title: Non-functional requirements + labels: + - NFR + - title: Bugfixes + labels: + - Bugfix + - title: Known issues + labels: + - wontfix + - title: Other changes + labels: + - "*" diff --git a/README.md b/README.md index 44327b260..907bd842f 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ Franklin site redesign for macktrucks.com ## Environments -- Preview: https://main--vg-macktrucks-com-rd--netcentric.hlx.page/ -- Live: https://main--vg-macktrucks-com-rd--netcentric.hlx.live/ +- Preview: https://main--vg-macktrucks-com--hlxsites.hlx.page/ +- Live: https://main--vg-macktrucks-com--hlxsites.hlx.live/ ## Installation diff --git a/blocks/eloqua-form/forms/electrifi.html b/blocks/eloqua-form/forms/electrifi.html new file mode 100644 index 000000000..73b9123c8 --- /dev/null +++ b/blocks/eloqua-form/forms/electrifi.html @@ -0,0 +1,1694 @@ + +
+ + + + +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ + + + + +
+
+ + + \ No newline at end of file diff --git a/blocks/eloqua-form/forms/magazine-subscribe.html b/blocks/eloqua-form/forms/magazine-subscribe.html index eab48e00d..da0625108 100644 --- a/blocks/eloqua-form/forms/magazine-subscribe.html +++ b/blocks/eloqua-form/forms/magazine-subscribe.html @@ -673,6 +673,10 @@ box-shadow:0 0 4px 0 #777; border-radius:2px; max-width:256px} + + #fe3317 option{ + color:black; + }
diff --git a/blocks/header/header.css b/blocks/header/header.css index 879f3a83d..bfc46641f 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -1,6 +1,7 @@ .header-wrapper { display: flex; justify-content: center; + z-index: 100; --menu-cards-gutter: 16px; --menu-animation: right 450ms ease-in-out; @@ -771,6 +772,7 @@ a.header__link { .header__accordion-container.header__main-link-wrapper { height: auto; + box-shadow: 0 0 3px 0 rgb(66 68 90 / 59%); } /* tabs styles - START */ diff --git a/blocks/performance-specifications/performance-specifications.js b/blocks/performance-specifications/performance-specifications.js index 23698a1b2..7607c20bb 100644 --- a/blocks/performance-specifications/performance-specifications.js +++ b/blocks/performance-specifications/performance-specifications.js @@ -160,7 +160,7 @@ function renderEngineSpecs(engineDetails) { ]) .flat()), p({ class: 'button-container' }, - a({ class: 'button secondary download-specs', href: engineDetails['download specs'], target: '_blank' }, 'Download Specs')), + a({ class: 'button secondary download-specs', href: engineDetails['learn more'], target: '_blank' }, 'Learn More')), ); } @@ -383,7 +383,7 @@ function parseEngineJsonData(data, block) { for (const [key, value] of modelArray) { if (key === 'rpm') { metricName = value; - } else if (key === 'model' || key === 'series' || key === 'download specs') { + } else if (key === 'model' || key === 'series' || key === 'learn more') { engine[key] = value; } else if (metricName !== null) { // handle performance data diff --git a/blocks/table/table.css b/blocks/table/table.css index ed0deeafa..67414806a 100644 --- a/blocks/table/table.css +++ b/blocks/table/table.css @@ -79,7 +79,7 @@ } .block.table.row-header td:first-child { - width: 20%; + width: 30%; border-right: none; } @@ -89,12 +89,24 @@ font-size: 18px; text-align: left; vertical-align: middle; - padding: 25px; + padding: 25px 5px; border-right: 1px solid #d3d3d3; } } -@media (max-width: 768px) { +@media (min-width: 991px) { + .block.table.row-header td:first-child p { + padding: 25px 15px; + } +} + +@media (min-width: 1200px) { + .block.table.row-header td:first-child p { + padding: 25px; + } +} + +@media (max-width: 767px) { .block.table.row-header table { width: 100%; } diff --git a/blocks/v2-cards/v2-cards.css b/blocks/v2-cards/v2-cards.css index 125b03939..b51976998 100644 --- a/blocks/v2-cards/v2-cards.css +++ b/blocks/v2-cards/v2-cards.css @@ -12,6 +12,10 @@ color: var(--c-primary-black); } +.v2-cards--no-background .v2-cards__card-item { + background: transparent; +} + .v2-cards--gray-cards .v2-cards__card-item { background: var(--c-tertiary-light-warm-gray); } @@ -24,6 +28,10 @@ padding: 24px; } +.v2-cards--no-background .v2-cards__text-wrapper { + padding: 40px 0 0; +} + .v2-cards__picture { display: flex; } @@ -35,6 +43,10 @@ object-fit: cover; } +.v2-cards--image-aspect-ratio-7-5 .v2-cards__image { + aspect-ratio: 7/5; +} + .v2-cards__heading { font-family: var(--ff-subheadings-medium); font-size: var(--headline-5-font-size); @@ -42,6 +54,11 @@ margin: 0 0 7px; } +.v2-cards--large-heading .v2-cards__heading { + font-size: var(--headline-4-font-size); + line-height: var(--headline-4-line-height); +} + .v2-cards__text-wrapper p { margin: 0; color: var(--c-primary-black); diff --git a/blocks/v2-cards/v2-cards.js b/blocks/v2-cards/v2-cards.js index 1c625e703..e67d622a1 100644 --- a/blocks/v2-cards/v2-cards.js +++ b/blocks/v2-cards/v2-cards.js @@ -2,7 +2,7 @@ import { variantsClassesToBEM } from '../../scripts/common.js'; export default async function decorate(block) { const blockName = 'v2-cards'; - const variantClasses = ['gray-cards', 'horizontal']; + const variantClasses = ['no-background', 'gray-cards', 'horizontal', 'image-aspect-ratio-7-5', 'large-heading']; variantsClassesToBEM(block.classList, variantClasses, blockName); const cardsItems = [...block.querySelectorAll(':scope > div')]; @@ -30,8 +30,22 @@ export default async function decorate(block) { buttons.forEach((el) => { el.classList.add(`${blockName}__button-container`); [...el.querySelectorAll('a')].forEach((link) => { - link.classList.add('standalone-link', `${blockName}__button`); - link.classList.remove('button', 'button--primary'); + const up = link.parentElement; + if ( + up.childNodes.length === 1 + && up.tagName === 'STRONG' + ) { + link.className = 'button button--small button--primary'; + } + if ( + up.childNodes.length === 1 + && up.tagName === 'EM' + ) { + link.className = 'button button--small button--secondary'; + } else { + link.classList.add('standalone-link', `${blockName}__button`); + link.classList.remove('button', 'button--primary'); + } }); }); } diff --git a/blocks/v2-tabbed-carousel/v2-tabbed-carousel.css b/blocks/v2-tabbed-carousel/v2-tabbed-carousel.css index 263307e30..53174b224 100644 --- a/blocks/v2-tabbed-carousel/v2-tabbed-carousel.css +++ b/blocks/v2-tabbed-carousel/v2-tabbed-carousel.css @@ -21,7 +21,7 @@ main .section.v2-tabbed-carousel-container { } .v2-tabbed-carousel__items { - align-items: flex-end; + align-items: flex-start; display: flex; flex-flow: row nowrap; margin: 0; @@ -81,6 +81,7 @@ main .section.v2-tabbed-carousel-container { list-style: none; margin: 0; overflow: auto; + scrollbar-width: none; padding: var(--navigation-padding); position: relative; } @@ -130,14 +131,26 @@ main .section.v2-tabbed-carousel-container { padding: 20px 15px 10px; white-space: nowrap; width: 100%; + transition: var(--duration-small) var(--easing-standard); + z-index: 3; + position: relative; } .v2-tabbed-carousel__navigation-item.active button, .v2-tabbed-carousel__navigation-item button:hover, -.v2-tabbed-carousel__navigation-item button:focus { +.v2-tabbed-carousel__navigation-item button:active, +.v2-tabbed-carousel__navigation-item button:focus-visible { color: var(--navigation-active-color); } +.v2-tabbed-carousel__navigation-item button:focus { + outline: 0; +} + +.v2-tabbed-carousel__navigation-item button:focus-visible { + outline: 3px solid var(--navigation-line-active-color); +} + @media (min-width: 1200px) { .v2-tabbed-carousel__figure { position: relative; diff --git a/blocks/v2-tabbed-carousel/v2-tabbed-carousel.js b/blocks/v2-tabbed-carousel/v2-tabbed-carousel.js index bd1d85286..918605fd3 100644 --- a/blocks/v2-tabbed-carousel/v2-tabbed-carousel.js +++ b/blocks/v2-tabbed-carousel/v2-tabbed-carousel.js @@ -1,4 +1,4 @@ -import { createElement, removeEmptyTags } from '../../scripts/common.js'; +import { createElement, unwrapDivs } from '../../scripts/common.js'; import { setCarouselPosition, listenScroll } from '../../scripts/carousel-helper.js'; const blockName = 'v2-tabbed-carousel'; @@ -12,43 +12,12 @@ const moveNavigationLine = (navigationLine, activeTab, tabNavigation) => { }); }; -function buildTabNavigation(tabItems, clickHandler) { - const tabNavigation = createElement('ul', { classes: `${blockName}__navigation` }); - const navigationLine = createElement('li', { classes: `${blockName}__navigation-line` }); - let timeout; - - [...tabItems].forEach((tabItem, i) => { - const listItem = createElement('li', { classes: `${blockName}__navigation-item` }); - const button = createElement('button'); - button.addEventListener('click', () => clickHandler(i)); - button.addEventListener('mouseover', (e) => { - clearTimeout(timeout); - moveNavigationLine(navigationLine, e.currentTarget, tabNavigation); - }); - - button.addEventListener('mouseout', () => { - timeout = setTimeout(() => { - const activeItem = document.querySelector(`.${blockName}__navigation-item.active`); - moveNavigationLine(navigationLine, activeItem, tabNavigation); - }, 600); - }); - - button.innerHTML = tabItem.dataset.carousel; - listItem.append(button); - tabNavigation.append(listItem); - }); - - tabNavigation.append(navigationLine); - - return tabNavigation; -} - const updateActiveItem = (elements, entry) => { elements.forEach((el, index) => { if (el === entry.target && entry.intersectionRatio >= 0.75) { - const carouselItems = document.querySelector(`.${blockName}__items`); - const navigation = document.querySelector(`.${blockName}__navigation`); - const navigationLine = document.querySelector(`.${blockName}__navigation-line`); + const carouselItems = el.parentElement; + const navigation = el.parentElement.nextElementSibling; + const navigationLine = navigation.querySelector(`.${blockName}__navigation-line`); [carouselItems, navigation].forEach((c) => c.querySelectorAll('.active').forEach((i) => i.classList.remove('active'))); carouselItems.children[index].classList.add('active'); @@ -74,44 +43,71 @@ const updateActiveItem = (elements, entry) => { }; export default function decorate(block) { - const container = block.querySelector(':scope > div'); - container.classList.add(`${blockName}__container`); + const carouselContainer = createElement('div', { classes: `${blockName}__container` }); + const carouselItems = createElement('ul', { classes: `${blockName}__items` }); + carouselContainer.append(carouselItems); - const carouselItems = createElement('div', { classes: `${blockName}__items` }); - container.appendChild(carouselItems); + const tabNavigation = createElement('ul', { classes: `${blockName}__navigation` }); + const navigationLine = createElement('li', { classes: `${blockName}__navigation-line` }); + let timeout; - const tabItems = block.querySelectorAll('.v2-tabbed-carousel__item'); + function buildTabNavigation(buttonContent, index) { + const listItem = createElement('li', { classes: `${blockName}__navigation-item` }); + const button = createElement('button'); - tabItems.forEach((tabItem) => { - const tabContent = tabItem.querySelector(':scope > div'); + button.addEventListener('click', () => setCarouselPosition(carouselItems, index)); + button.addEventListener('mouseover', (e) => { + clearTimeout(timeout); + moveNavigationLine(navigationLine, e.currentTarget, tabNavigation); + }); + button.addEventListener('mouseout', () => { + timeout = setTimeout(() => { + const activeItem = document.querySelector(`.${blockName}__navigation-item.active`); + moveNavigationLine(navigationLine, activeItem, tabNavigation); + }, 600); + }); + + button.innerHTML = buttonContent; + listItem.append(button); + + return listItem; + } + + const tabItems = block.querySelectorAll(':scope > div'); + tabItems.forEach((tabItem, index) => { + const liItem = createElement('li', { classes: `${blockName}__item` }); const figure = createElement('figure', { classes: `${blockName}__figure` }); - const picture = tabItem.querySelector('picture'); - figure.appendChild(picture); + const tabContent = tabItem.querySelector('p'); + + figure.append(tabContent.querySelector('picture')); const figureCaption = createElement('figcaption'); - const text = tabContent?.querySelectorAll(':scope > *'); - if (text) { - figureCaption.append(...text); + const lastItems = [...tabContent.childNodes].at(-1); + if (lastItems.nodeType === Node.TEXT_NODE) { + figureCaption.append(lastItems); + figure.append(figureCaption); } - tabContent.remove(); figure.appendChild(figureCaption); - - tabItem.prepend(figure); - - carouselItems.appendChild(tabItem); + liItem.append(figure); + carouselItems.appendChild(liItem); + + // navigation item + const tabTitle = tabItem.querySelector('h3'); + const navItem = buildTabNavigation(tabTitle.innerHTML, index); + tabNavigation.append(navItem); + tabTitle.remove(); + tabItem.innerHTML = ''; }); - removeEmptyTags(container); - - const tabNavigation = buildTabNavigation(tabItems, (index) => { - setCarouselPosition(carouselItems, index); - }); + tabNavigation.append(navigationLine); + carouselContainer.append(tabNavigation); - container.append(tabNavigation); + block.append(carouselContainer); // update the button indicator on scroll const elements = carouselItems.querySelectorAll(':scope > *'); listenScroll(carouselItems, elements, updateActiveItem, 0.75); + unwrapDivs(block); } diff --git a/blocks/vin-number/vin-number.css b/blocks/vin-number/vin-number.css new file mode 100644 index 000000000..118b379b9 --- /dev/null +++ b/blocks/vin-number/vin-number.css @@ -0,0 +1,132 @@ +.vin-number-container { + padding: 0; +} + +.vin-number__form { + display: flex; + gap: 8px; + flex-direction: column; +} + +.vin-number__input-wrapper { + position: relative; +} + +.redesign-v2 .vin-number__form .vin-number__submit { + padding-top: 11px; + padding-bottom: 11px; +} + +.vin-number__input { + margin: 0; + max-width: 100%; + font-size: var(--body-font-size-xs); +} + +.vin-number__label { + left: 16px; + pointer-events: none; + position: absolute; + top: 50%; + transform: translateY(-50%); + transition: + top var(--duration-small) var(--easing-standard), + left var(--duration-small) var(--easing-standard); + font-size: var(--body-font-size-xs); +} + +.vin-number__input:focus ~ .vin-number__label, +.vin-number__input:not(:placeholder-shown) ~ .vin-number__label, +.vin-number__input:not(:focus):valid ~ .v2-forms__label { + bottom: 0; + left: 0; + top: 0; +} + +/* recalls list styling */ +.vin-number__results-container{ + padding: 20px 0; +} + +.vin-number__recalls-wrapper { + margin-top: 40px; +} + +.vin-number__recalls-heading-wrapper { + display: flex; + gap: 16px; + flex-wrap: wrap; +} + +.vin-number__recalls-heading { + text-transform: uppercase; +} + +.vin-number__recalls-refresh-date, +.vin-number__recalls-heading { + margin-bottom: 0; +} + +.vin-number__recalls-alert-icon { + align-self: flex-end; +} + +.vin-number__recalls-refresh-date { + align-self: center; +} + +.vin-number__list, +.vin-number__detail-list { + list-style: none; + padding: 0; + margin: 0; +} + +.vin-number__list-item { + border-top: 1px solid var(--c-primary-black); + padding: 20px 0; +} + +.vin-number__item-title { + margin-bottom: 0; +} + +.vin-number__detail-item { + display: flex; + gap: 16px; +} + +.vin-number__detail-item--column { + flex-direction: column; + gap: 0; +} + +.vin-number__detail-item:not(:first-child){ + margin-top: 10px; +} + +.vin-number__detail-title { + margin-bottom: 0; + margin-top: 0; +} + +.vin-number__recall-incomplete, +.vin-number__recall-incomplete-no-remedy { + color: var(--c-accent-red); +} + +.vin-number__recall-complete { + color: #78B833; +} + +@media (min-width: 744px) { + .vin-number__form { + flex-direction: row; + max-width: 100%; + align-items: center; + } + + .vin-number__input-wrapper { + flex: 1; + } +} diff --git a/blocks/vin-number/vin-number.js b/blocks/vin-number/vin-number.js new file mode 100644 index 000000000..a1bb75ce4 --- /dev/null +++ b/blocks/vin-number/vin-number.js @@ -0,0 +1,189 @@ +import { getTextLabel, createElement, getJsonFromUrl } from '../../scripts/common.js'; + +const VIN_URL = 'https://vinlookup-dev-euw-ase-01.azurewebsites.net/v1/api/vin/'; +const API_KEY = '0e13506b59674706ad9bae72d94fc83c'; + +const docRange = document.createRange(); + +// list of things to be display for each recall +const valueDisplayList = [{ + key: 'recall_date', +}, +{ + key: 'mfr_recall_number', +}, +{ + key: 'nhtsa_recall_number', +}, +{ + key: 'mfr_recall_status', +}, +{ + key: 'recall_description', + class: 'vin-number__detail-item--column', +}, +{ + key: 'safety_risk_description', + class: 'vin-number__detail-item--column', +}, { + key: 'remedy_description', + class: 'vin-number__detail-item--column', +}, { + key: 'mfr_notes', + class: 'vin-number__detail-item--column', +}]; + +// use this to map values from API +const recallStatus = { + 11: 'recall_incomplete', + 0: 'recall_complete', + 12: 'recall_incomplete_no_remedy', +}; + +function capitalize(text) { + return text.toLowerCase().split('').map((char, index) => (index === 0 ? char.toUpperCase() : char)).join(''); +} + +function renderRecalls(recallsData) { + const resultText = document.querySelector('.vin-number__results-text'); + resultText.innerText = getTextLabel('result text').replace(/\${count}/, recallsData.number_of_recalls).replace(/\${vin}/, recallsData.vin); + + if (recallsData.recalls_available) { + const blockEl = document.querySelector('.vin-number__recalls-wrapper'); + const listWrapperFragment = docRange.createContextualFragment(` +
+ + + + + +

${getTextLabel('recalls')}    

+

[${getTextLabel('published_info')}: ${recallsData.refresh_date} | ${getTextLabel('recall_oldest_info')}]

+
+ `); + + // create each recall + const list = createElement('ul', { classes: 'vin-number__list' }); + recallsData.recalls.forEach((recall) => { + const liEl = createElement('li', { + classes: 'vin-number__list-item', + }); + + // map the number from api to correct status + recall.mfr_recall_status = recallStatus[recall.mfr_recall_status]; + + const recallDetailsList = createElement('ul', { classes: 'vin-number__detail-list' }); + + valueDisplayList.forEach((item) => { + if (recall[item.key]) { + const recallClass = item.key === 'mfr_recall_status' ? `vin-number__${recall.mfr_recall_status.replace(/_/g, '-').toLowerCase()}` : ''; + let itemValue = item.class ? capitalize(recall[item.key]) : recall[item.key]; + + if (recallClass) { + itemValue = getTextLabel(recall[item.key]); + } + + const itemFragment = docRange.createContextualFragment(`
  • +
    ${getTextLabel(item.key)}
    + ${itemValue} +
  • `); + recallDetailsList.append(...itemFragment.children); + } + }); + liEl.append(recallDetailsList); + list.append(liEl); + }); + + blockEl.append(listWrapperFragment); + blockEl.appendChild(list); + } +} + +async function fetchRecalls(e) { + e.preventDefault(); + if (e && e.target) { + // disable submit while fetching data + const submitBtn = e.target.querySelector('button'); + submitBtn.disabled = true; + + const recalls = document.querySelector('.vin-number__recalls-wrapper'); + recalls.innerHTML = ''; + + const resultText = document.querySelector('.vin-number__results-text'); + resultText.innerText = getTextLabel('loading recalls'); + + const formData = new FormData(e.target); + const vin = formData.get('vin'); + + if (vin) { + try { + getJsonFromUrl(`${VIN_URL}${vin}?api_key=${API_KEY}&mode=company`) + .then((response) => { + if (response.error_code) { + resultText.innerHTML = `${getTextLabel('no recalls')} ${vin}`; + } else { + response.recalls.sort((a, b) => (b.mfr_recall_status - a.mfr_recall_status) + || (new Date(b.date) - new Date(a.date))); + renderRecalls(response); + } + + const vinInput = document.querySelector('.vin-number__input'); + vinInput.value = ''; + submitBtn.disabled = false; + }); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error fetching Recalls:', error); + } + return null; + } + } + return null; +} + +export default async function decorate(block) { + const form = createElement('form', { + classes: ['vin-number__form'], + }); + const formChildren = document.createRange().createContextualFragment(` +
    + + +
    + + `); + + const vinResultsContainer = createElement('div', { classes: 'vin-number__results-container' }); + const innerContent = docRange.createContextualFragment(` + +
    + `); + + vinResultsContainer.append(innerContent); + + form.addEventListener('submit', fetchRecalls, false); + form.append(...formChildren.children); + block.append(form); + block.append(vinResultsContainer); + + const vinInput = block.querySelector('.vin-number__input'); + + vinInput.oninvalid = (e) => { + e.target.setCustomValidity(getTextLabel('vinformat')); + }; + + vinInput.oninput = (e) => { + e.target.setCustomValidity(''); + }; +} diff --git a/files/rt-side-stand-up-interferences-lr-v2-pptx-6-5-2017-3.pptx b/files/rt-side-stand-up-interferences-lr-v2-pptx-6-5-2017-3.pptx new file mode 100644 index 000000000..81e1b2cc1 Binary files /dev/null and b/files/rt-side-stand-up-interferences-lr-v2-pptx-6-5-2017-3.pptx differ diff --git a/files/shim-calculator.xlsx b/files/shim-calculator.xlsx new file mode 100644 index 000000000..77d15d0f6 Binary files /dev/null and b/files/shim-calculator.xlsx differ diff --git a/fstab.yaml b/fstab.yaml index 1b9bab1c5..1772b0b51 100644 --- a/fstab.yaml +++ b/fstab.yaml @@ -1,2 +1,2 @@ mountpoints: - /: https://adobe.sharepoint.com/sites/HelixProjects/Shared%20Documents/sites/VolvoGroup/vg-macktrucks-com-redesign + /: https://adobe.sharepoint.com/sites/HelixProjects/Shared%20Documents/sites/VolvoGroup/vg-macktrucks-com diff --git a/mack-news/feed.xml b/mack-news/feed.xml index 2644d50bc..92a855290 100644 --- a/mack-news/feed.xml +++ b/mack-news/feed.xml @@ -2,7 +2,7 @@ https://www.macktrucks.com/mack-news/ Mack News - 2023-10-02T00:00:00.000Z + 2023-10-30T00:00:00.000Z AEM Project Franklin News feed generator (GitHub action) Get the latest news from Mack® Trucks and see how we are taking our Born Ready semi truck line to the next level with new innovations and technology. @@ -2641,4 +2641,68 @@ 2023-10-02T00:00:00.000Z + + <![CDATA[Mack Showcases Extensive Capabilities of the Mack Anthem® at ATA MC&E | Mack Trucks]]> + https://www.macktrucks.com/mack-news/2023/mack-showcases-extensive-capabilities-of-the-mack-anthem-at-ata-mce + + 2023-10-03T00:00:00.000Z + + 2023-10-03T00:00:00.000Z + + + <![CDATA[Mack Defense to Show Mack® AC Model at AUSA 2023 | Mack Trucks]]> + https://www.macktrucks.com/mack-news/2023/mack-defense-to-show-mack-ac-model-at-ausa + + 2023-10-04T00:00:00.000Z + + 2023-10-04T00:00:00.000Z + + + <![CDATA[UAW Members Reject Agreement with Mack Trucks, Announce Strike | Mack Trucks]]> + https://www.macktrucks.com/mack-news/2023/uaw-members-reject-agreement-with-mack-trucks-announce-strike + + 2023-10-09T00:00:00.000Z + + 2023-10-09T00:00:00.000Z + + + <![CDATA[Mack Trucks Announces Continued Sponsorship of the ATA Share the Road and Workforce Heroes Programs | Mack Trucks]]> + https://www.macktrucks.com/mack-news/2023/mack-trucks-announces-continued-sponsorship-of-the-ata-share-the-road-and-workforce-heroes-programs + + 2023-10-16T00:00:00.000Z + + 2023-10-16T00:00:00.000Z + + + <![CDATA[Mack Trucks Introduces Mack® Connect, a Comprehensive Fleet Management Portal | Mack Trucks]]> + https://www.macktrucks.com/mack-news/2023/mack-trucks-introduces-mack-connect-a-comprehensive-fleet-management-portal + + 2023-10-16T00:00:00.000Z + + 2023-10-16T00:00:00.000Z + + + <![CDATA[New UAW Demands Ignore Months of Good Faith Bargaining | Mack Trucks]]> + https://www.macktrucks.com/mack-news/2023/new-uaw-demands-ignore-months-of-good-faith-bargaining + + 2023-10-19T00:00:00.000Z + + 2023-10-19T00:00:00.000Z + + + <![CDATA[Mack Trucks Statement Regarding UAW Negotiations | Mack Trucks]]> + https://www.macktrucks.com/mack-news/2023/mack-trucks-statement-regarding-uaw-negotiations + + 2023-10-27T00:00:00.000Z + + 2023-10-27T00:00:00.000Z + + + <![CDATA[Mack Trucks Introduces ElectriFi Subscription Exclusively for Mack® MD Electric Vehicles| Mack Trucks]]> + https://www.macktrucks.com/mack-news/2023/mack-trucks-introduces-electrifi-subscription-exclusively-for-mack-md-electric-vehicles + + 2023-10-30T00:00:00.000Z + + 2023-10-30T00:00:00.000Z + \ No newline at end of file diff --git a/placeholder.json b/placeholder.json index 6ea5600bc..4595f01b1 100644 --- a/placeholder.json +++ b/placeholder.json @@ -99,6 +99,86 @@ "Key": "no eloqua link message", "Text": "Change cookie settings" }, + { + "Key": "vinlabel", + "Text": "Enter your 17-digit VIN (Vehicle Identification Number)" + }, + { + "Key": "submit", + "Text": "Submit" + }, + { + "Key": "vinformat", + "Text": "Please provide correct vin number format" + }, + { + "Key": "result text", + "Text": "${count} recalls available for \"${vin}\" VIN" + }, + { + "Key": "recalls", + "Text": "Recalls" + }, + { + "Key": "recall_date", + "Text": "Issue date" + }, + { + "Key": "recall_description", + "Text": "Description" + }, + { + "Key": "safety_risk_description", + "Text": "Safety Risk" + }, + { + "Key": "remedy_description", + "Text": "Remedy" + }, + { + "Key": "published_info", + "Text": "Information last updated" + }, + { + "Key": "mfr_recall_status", + "Text": "Recall Status" + }, + { + "Key": "recall_complete", + "Text": "Recall Complete" + }, + { + "Key": "recall_incomplete", + "Text": "Recall Incomplete" + }, + { + "Key": "recall_incomplete_no_remedy", + "Text": "Recall In Complete, remedy not available" + }, + { + "Key": "loading recalls", + "Text": " Loading Recalls ....." + }, + { + "Key": "no recalls", + "Text": "No recalls for vin" + }, + { + "Key": "mfr_notes", + "Text": "Next steps" + }, + { + "Key": "mfr_recall_number", + "Text": "Brand Recall Number" + }, + { + "Key": "nhtsa_recall_number", + "Text": "NHTSA recall number" + }, + { + "Key": "recall_oldest_info", + "Text": "Recall information available since: Jan 15,2008" + }, { "Key": "All trucks", "Text": "All trucks" diff --git a/scripts/common.js b/scripts/common.js index f515f5c73..8b470ec79 100644 --- a/scripts/common.js +++ b/scripts/common.js @@ -204,6 +204,24 @@ export function debounce(func, timeout = 200) { }; } +/** + * Returns a list of properties listed in the block + * @param {string} route get the Json data from the route + * @returns {Object} the json data object +*/ +export const getJsonFromUrl = async (route) => { + try { + const response = await fetch(route); + if (!response.ok) return null; + const json = await response.json(); + return json; + } catch (error) { + // eslint-disable-next-line no-console + console.error('getJsonFromUrl:', { error }); + } + return null; +}; + /* The generateId function should be used only for generating the id for UI elements diff --git a/scripts/delayed.js b/scripts/delayed.js index de844cc0a..c1bc60d41 100644 --- a/scripts/delayed.js +++ b/scripts/delayed.js @@ -1,20 +1,27 @@ // eslint-disable-next-line import/no-cycle import { sampleRUM, loadScript } from './lib-franklin.js'; +const COOKIES = { + performance: 'C0002:1', +}; + // Core Web Vitals RUM collection sampleRUM('cwv'); -const cookieSetting = decodeURIComponent(document.cookie.split(';').find((cookie) => cookie.trim().startsWith('OptanonConsent='))); -const isGtmAllowed = cookieSetting.includes('C0002:1'); +const cookieSetting = decodeURIComponent(document.cookie.split(';') + .find((cookie) => cookie.trim().startsWith('OptanonConsent='))); +const isPerformanceAllowed = cookieSetting.includes(COOKIES.performance); -if (isGtmAllowed) { +if (isPerformanceAllowed) { loadGoogleTagManager(); + loadHotjar(); } // add more delayed functionality here // Prevent the cookie banner from loading when running in library -if (!window.location.pathname.includes('srcdoc') && (!window.location.host.includes('hlx.page') && !window.location.host.includes('localhost'))) { +if (!window.location.pathname.includes('srcdoc') + && !['localhost', 'hlx.page'].some((url) => window.location.host.includes(url))) { loadScript('https://cdn.cookielaw.org/scripttemplates/otSDKStub.js', { type: 'text/javascript', charset: 'UTF-8', @@ -51,11 +58,13 @@ async function loadGoogleTagManager() { } // Hotjar -/* eslint-disable */ -(function(h,o,t,j,a,r){ - h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; - h._hjSettings={hjid:597204,hjsv:6}; a=o.getElementsByTagName('head')[0]; - r=o.createElement('script');r.async=1; r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv; - a.appendChild(r); -})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv='); -/* eslint-enable */ +async function loadHotjar() { + /* eslint-disable */ + (function(h,o,t,j,a,r){ + h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; + h._hjSettings={hjid:597204,hjsv:6}; a=o.getElementsByTagName('head')[0]; + r=o.createElement('script');r.async=1; r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv; + a.appendChild(r); + })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv='); + /* eslint-enable */ +} diff --git a/scripts/scripts.js b/scripts/scripts.js index c21839c6a..64c13f91e 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -369,46 +369,6 @@ function buildInpageNavigationBlock(main, classname) { } } -function createTabbedSection(tabItems, classname) { - const tabSection = createElement('div', { classes: 'section' }); - tabSection.dataset.sectionStatus = 'initialized'; - const tabBlock = buildBlock(classname, [tabItems]); - tabSection.append(tabBlock); - return tabSection; -} - -function buildTabbedBlock(main, classname) { - let nextElement; - const tabItems = []; - const mainChildren = [...main.querySelectorAll(':scope > div')]; - - mainChildren.forEach((section, i2) => { - const isCarousel = section.dataset.carousel; - if (!isCarousel) return; - - nextElement = mainChildren[i2 + 1]; - const tabContent = createElement('div', { classes: `${classname}__item` }); - tabContent.dataset.carousel = section.dataset.carousel; - tabContent.innerHTML = section.innerHTML; - const image = tabContent.querySelector('p > picture'); - - tabContent.prepend(image); - - tabItems.push(tabContent); - section.remove(); - }); - - if (tabItems.length > 0) { - const tabbedCarouselSection = createTabbedSection(tabItems, classname); - if (nextElement) { // if we saved a position push the carousel in that position if not - main.insertBefore(tabbedCarouselSection, nextElement); - } else { - main.append(tabbedCarouselSection); - } - decorateBlock(tabbedCarouselSection.querySelector(`.${classname}`)); - } -} - /** * Decorates the main element. * @param {Element} main The main element @@ -428,8 +388,6 @@ export function decorateMain(main, head) { buildTruckLineupBlock(main, 'v2-truck-lineup'); // Inpage navigation buildInpageNavigationBlock(main, 'v2-inpage-navigation'); - // V2 tabbed carousel - buildTabbedBlock(main, 'v2-tabbed-carousel'); } async function loadTemplate(doc, templateName) { diff --git a/scripts/video-helper.js b/scripts/video-helper.js index 110287e58..daa1e157c 100644 --- a/scripts/video-helper.js +++ b/scripts/video-helper.js @@ -42,7 +42,7 @@ export function createLowResolutionBanner() { export function showVideoModal(linkUrl) { // eslint-disable-next-line import/no-cycle import('../common/modal/modal-component.js').then((modal) => { - let beforeBanner = null; + let beforeBanner = {}; if (isLowResolutionVideoUrl(linkUrl)) { beforeBanner = createLowResolutionBanner();