Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coveo tech #1369

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
252 changes: 15 additions & 237 deletions blocks/resources/resources.js
Original file line number Diff line number Diff line change
@@ -1,231 +1,6 @@
import {
createOptimizedPicture, decorateBlock, decorateIcons,
fetchPlaceholders, getMetadata, loadBlock, loadCSS,
} from '../../scripts/lib-franklin.js';
import {
loadScript, embedVideo, fetchFragment, isGatedResource, summariseDescription,
} from '../../scripts/scripts.js';
import { getMetadata, loadCSS } from '../../scripts/lib-franklin.js';
import { loadScript } from '../../scripts/scripts.js';
import { getCoveoToken } from '../coveo-search/coveo-search.js';
import {
div, a, p, h3, i, h2, span, ul, li,
} from '../../scripts/dom-helpers.js';
import ffetch from '../../scripts/ffetch.js';
import resourceMapping from './resource-mapping.js';

const relatedResourcesHeaders = {
Product: 'relatedProducts',
Technology: 'relatedTechnologies',
Application: 'relatedApplications',
};
const videoResourceTypes = ['Videos and Webinars', 'Interactive Demo'];
const excludedResourcesProducts = ['Citation', 'COA', ...videoResourceTypes];
const excludedResourcesApplications = ['COA', ...videoResourceTypes];

function handleFilterClick(e) {
e.preventDefault();
const { target } = e;
const targetFilter = target.closest('li.filter');

// toggle filters dropdown on mobile
const targetFilters = target.closest('.filters');
targetFilters.classList.toggle('dropdown');

const selected = targetFilter.getAttribute('aria-selected') === 'true';
if (!selected) {
const resourceType = targetFilter.getAttribute('aria-labelledby');
const allFilters = document.querySelectorAll('.filter');
allFilters.forEach((item) => item.setAttribute('aria-selected', false));
targetFilter.setAttribute('aria-selected', true);
if (resourceType === 'View All') {
const filteredResources = document.querySelectorAll('.filtered-item');
filteredResources.forEach((item) => item.setAttribute('aria-hidden', false));
} else {
// hide all displayed items
const filteredResources = document.querySelectorAll('.filtered-item');
filteredResources.forEach((item) => item.setAttribute('aria-hidden', true));
// show filtered items
const selectedResources = document.querySelectorAll(`.filtered-item[aria-labelledby="${resourceType}"]`);
selectedResources.forEach((item) => item.setAttribute('aria-hidden', false));
}
}
}

export async function decorateResources(block) {
const template = getMetadata('template');
const identifier = getMetadata('identifier') || document.querySelector('.hero .container h1, .hero-advanced .container h1').textContent;

const includedResourceTypes = Object.keys(resourceMapping);
const relatedResource = relatedResourcesHeaders[template] || 'relatedProducts';

const resources = await ffetch('/query-index.json')
.sheet('resources')
.filter((resource) => resource[relatedResource].includes(identifier)
&& includedResourceTypes.includes(resource.type))
.all();
const excludedResources = template === 'Application' ? excludedResourcesApplications : excludedResourcesProducts;
const otherResources = resources.filter((item) => !excludedResources.includes(item.type));
const videoResources = resources.filter((item) => videoResourceTypes.includes(item.type));

const filtersBlock = ul({ class: 'filters' });
const filters = [...new Set(otherResources.map((item) => item.type))];
if (videoResources.length > 0) {
filters.push('Videos and Webinars');
}
const sortedFilters = filters.sort((x, y) => (x.toLowerCase() < y.toLowerCase() ? -1 : 1));
sortedFilters.unshift('View All');

const placeholders = await fetchPlaceholders();
const displayFilters = {};
displayFilters['View All'] = placeholders.viewAll || 'View All';
displayFilters['Videos and Webinars'] = placeholders.videosAndWebinars || 'Videos and Webinars';

const otherResourcesBlock = div({ class: 'resources-section' });
otherResources.forEach((item) => {
const resourceType = item.type;
const resourceDisplayType = item.displayType;
const resourceImage = resourceMapping[item.type]?.image;
const resourceLink = isGatedResource(item) ? item.gatedURL : item.path;
displayFilters[resourceType] = resourceDisplayType;

const resourceBlock = div(
{
class: 'resource filtered-item',
'aria-hidden': false,
'aria-labelledby': resourceType,
},
div(
{ class: 'resource-icon' },
createOptimizedPicture(
`/images/resource-icons/${resourceImage}.png`,
resourceImage,
false,
[{ media: '(max-width: 991px)', width: '35' }, { width: '60' }],
),
),
div(
{ class: 'resource-info' },
div(
{ class: 'resource-header' },
p(item.displayType),
h3(item.title),
),
div(
{ class: 'resource-description' },
item.description && item.description !== '0' ? summariseDescription(item.description, 230) : '',
),
div(
{ class: 'resource-actions' },
p(
{ class: 'resource-link' },
a(
{ href: resourceLink },
placeholders[resourceMapping[resourceType]?.action] || 'View Resource',
i({ class: 'fa fa-chevron-circle-right' }),
),
),
),
),
);
otherResourcesBlock.append(resourceBlock);
});

let videoResourcesBlock = null;
if (videoResources.length > 0) {
videoResourcesBlock = div({
class: 'videos-container filtered-item',
'aria-hidden': false,
'aria-labelledby': 'Videos and Webinars',
});

const videosContainerBlock = div({ class: 'resources-section' });
await Promise.all(videoResources.map(async (item) => {
displayFilters[item.type] = item.displayType;
// eslint-disable-next-line no-nested-ternary
const imageSrc = item.thumbnail && item.thumbnail !== '0'
? item.thumbnail
: (item.image && item.image !== '0'
? item.image : '/images/default-card-thumbnail.webp');
if (isGatedResource(item)) {
const videoWrapper = div({ class: 'video-wrapper' },
div({ class: 'video-container' },
div({ class: 'vidyard-video-placeholder' },
createOptimizedPicture(imageSrc),
a({ href: item.gatedURL, target: '_blank' },
div({ class: 'play-button' },
div({ class: 'play-button-size' }),
div({ class: 'arrow-size' },
div({ class: 'arrow-size-ratio' }),
div({ class: 'arrow' }),
),
),
),
),
),
p({ class: 'video-title' }, item.title),
);
videosContainerBlock.append(videoWrapper);
} else {
const videoFragmentHtml = await fetchFragment(item.path);
const videoFragment = document.createElement('div');
videoFragment.innerHTML = videoFragmentHtml;
const videoElement = videoFragment.querySelector('a[href^="https://share.vidyard.com/watch/"], a[href^="https://view.ceros.com/molecular-devices/"]');
const videoHref = videoElement?.href;
if (videoElement && videoHref && videoHref.startsWith('https://')) {
const videoURL = new URL(videoHref);
const videoWrapper = div({ class: 'video-wrapper' },
div({ class: 'video-container' }),
p({ class: 'video-title' }, item.title),
);
const videoContainer = videoWrapper.querySelector('.video-container');
const videoLinkElement = a({ href: videoHref }, videoHref);
if (item.type === 'Interactive Demo') {
videoContainer.append(
div({ class: 'ceros' },
createOptimizedPicture(imageSrc),
videoLinkElement,
),
);
const cerosBlock = videoContainer.querySelector('.ceros');
decorateBlock(cerosBlock);
await loadBlock(cerosBlock);
} else {
videoContainer.append(videoLinkElement);
embedVideo(videoWrapper.querySelector('a'), videoURL, 'lightbox');
}
videosContainerBlock.append(videoWrapper);
}
}
}));

videoResourcesBlock.append(h2({ class: 'video-resources-title' }, displayFilters['Videos and Webinars'] || 'Videos and Webinars'));
videoResourcesBlock.append(videosContainerBlock);
}

sortedFilters.forEach((filter, idx) => {
filtersBlock.append(
li({
class: 'filter',
'aria-labelledby': filter,
'aria-selected': idx === 0,
onclick: handleFilterClick,
}, span({ class: 'filter-divider' }, idx === 0 ? '' : '|'), a({
href: '#',
}, displayFilters[filter] || filter), span({ class: 'icon icon-chevron-right-outline' }),
),
);
});
if (window.matchMedia('only screen and (max-width: 767px)').matches) {
decorateIcons(filtersBlock);
}

block.append(filtersBlock);
block.append(otherResourcesBlock);
if (videoResourcesBlock) {
block.append(videoResourcesBlock);
}

return block;
}

function searchFormHeader() {
return `
Expand Down Expand Up @@ -266,6 +41,7 @@ function searchMainSection() {
<div class="CoveoDynamicFacet" data-enable-scroll-to-top="false" data-title="Country" data-field="@md_country" data-tab="SDS" data-id="Country" data-number-of-values="" data-enable-facet-search="false"></div>
<div class="CoveoDynamicHierarchicalFacet coveo-dynamic-hierarchical-facet" data-enable-facet-search="false" data-delimiting-character="|" data-title="Products" data-field="@mdproductsdatacategory" data-tab="Products, All, Resources, KBArticles, Videos" data-number-of-values="8" data-enable-collapse="true" data-enable-scroll-to-top="false" data-filter-facet-count="false"></div>
<div class="CoveoDynamicHierarchicalFacet coveo-dynamic-hierarchical-facet" data-enable-facet-search="false" data-delimiting-character="|" data-title="Applications" data-field="@mdapplicationsdatacategory" data-tab="Applications, All, Resources, KBArticles, Videos" data-number-of-values="8" data-enable-collapse="true" data-enable-scroll-to-top="false" data-filter-facet-count="false"></div>
<div class="CoveoDynamicHierarchicalFacet coveo-dynamic-hierarchical-facet" data-enable-facet-search="false" data-delimiting-character="|" data-title="Technologies" data-field="@mdtechnologydatacategory" data-tab="Technology, All, Resources, KBArticles, Videos" data-number-of-values="8" data-enable-collapse="true" data-enable-scroll-to-top="false" data-filter-facet-count="false"></div>
<div class="CoveoDynamicFacet" data-enable-scroll-to-top="false" data-title="Languages" data-field="@md_lang" data-tab="SDS" data-number-of-values="" data-depends-on="Country"></div>
<div class="CoveoDynamicFacet" data-enable-scroll-to-top="false" data-title="Type" data-field="@objecttype" data-tab="Resources"></div>
<div class="CoveoDynamicFacet" data-enable-scroll-to-top="false" data-title="Content Type" data-enable-facet-search="false" data-field="@md_contenttype" data-number-of-values="8" data-tab="Resources, All"></div>
Expand Down Expand Up @@ -403,10 +179,16 @@ export async function coveoResources(target) {
const url = new URL(window.location.href);
const landingPageType = getMetadata('template');

if (landingPageType === 'Product' || landingPageType === 'Application') {
if (
landingPageType === 'Product'
|| landingPageType === 'Application'
|| landingPageType === 'Technology'
) {
if (target.hash.toLowerCase() === `#${coveoTabName}`) {
const category = encodeURIComponent(getMetadata('category').trim());
const subCategory = encodeURIComponent(getMetadata('sub-category').trim());
const subCategory = encodeURIComponent(
getMetadata('sub-category').trim(),
);
let searchTitle = encodeURIComponent(getMetadata('search-title').trim());
if (!searchTitle) {
searchTitle = document.querySelector('main h1').textContent;
Expand All @@ -426,6 +208,10 @@ export async function coveoResources(target) {
url.hash = `t=Resources&sort=relevancy&f:@mdapplicationsdatacategory=[${params}]`;
}

if (landingPageType === 'Technology') {
url.hash = `t=Resources&sort=relevancy&f:@mdtechnologydatacategory=[${params}]`;
}

window.history.replaceState(null, null, url);
await initializeCoveo(resourcesBlock);
setTimeout(() => {
Expand All @@ -434,11 +220,3 @@ export async function coveoResources(target) {
}
}
}

export default async function decorate(block) {
const landingPageType = getMetadata('template');

if (landingPageType === 'Technology') {
await decorateResources(block);
}
}
22 changes: 11 additions & 11 deletions content-sitemap.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.moleculardevices.com/products/clone-screening/accessories-consumables/qpix</loc>
<xhtml:link rel="alternate" hreflang="de" href="https://de.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="it" href="https://it.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="es" href="https://es.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="fr" href="https://fr.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="ko" href="https://ko.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://www.moleculardevices.com.cn/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<lastmod>2024-04-25</lastmod>
</url>
<url>
<loc>https://www.moleculardevices.com/products/clone-screening/accessories-consumables/qrep-replicator</loc>
<xhtml:link rel="alternate" hreflang="de" href="https://de.moleculardevices.com/products/clone-screening/accessories-consumables/qrep-replicator"/>
Expand Down Expand Up @@ -3905,17 +3916,6 @@
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.moleculardevices.com/applications/cell-viability-proliferation-cytotoxicity-assays"/>
<lastmod>2023-10-03</lastmod>
</url>
<url>
<loc>https://www.moleculardevices.com/products/clone-screening/accessories-consumables/qpix</loc>
<xhtml:link rel="alternate" hreflang="de" href="https://de.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="it" href="https://it.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="es" href="https://es.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="fr" href="https://fr.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="ko" href="https://ko.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="zh" href="https://www.moleculardevices.com.cn/products/clone-screening/accessories-consumables/qpix"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.moleculardevices.com/products/clone-screening/accessories-consumables/qpix"/>
<lastmod>2023-10-03</lastmod>
</url>
<url>
<loc>https://www.moleculardevices.com/products/additional-products</loc>
<xhtml:link rel="alternate" hreflang="de" href="https://de.moleculardevices.com/products/additional-products"/>
Expand Down
2 changes: 1 addition & 1 deletion coveo/coveo-xml.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78734,7 +78734,7 @@
<md_pagesort>1</md_pagesort>
</url>
<url>
<loc>https://www.moleculardevices.com/sites/default/files/en/assets/user-guide/br/aquamax-userguide-01120151r.pdf</loc>
<loc>https://www.moleculardevices.com/sites/default/files/en/assets/user-guide/br/aquamax-userguide-01120151s.pdf</loc>
<lastmod>2020-11-25T00:00:00.000Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
Expand Down
Loading
Loading