Form Success
diff --git a/libs/blocks/marketo/marketo.js b/libs/blocks/marketo/marketo.js
index a6cfb7a2e7..1602d0694a 100644
--- a/libs/blocks/marketo/marketo.js
+++ b/libs/blocks/marketo/marketo.js
@@ -19,14 +19,20 @@ const ROOT_MARGIN = 1000;
const FORM_ID = 'form id';
const BASE_URL = 'marketo host';
const MUNCHKIN_ID = 'marketo munckin';
+const SUCCESS_TYPE = 'form.success.type';
+const SUCCESS_CONTENT = 'form.success.content';
+const SUCCESS_SECTION = 'form.success.section';
const FORM_MAP = {
- 'destination-url': 'form.success.content',
+ 'success-type': SUCCESS_TYPE,
+ 'destination-type': SUCCESS_TYPE,
+ 'success-content': SUCCESS_CONTENT,
+ 'destination-url': SUCCESS_CONTENT,
+ 'success-section': SUCCESS_SECTION,
'co-partner-names': 'program.copartnernames',
'sfdc-campaign-id': 'program.campaignids.sfdc',
};
-export const formValidate = (form) => {
- const formEl = form.getFormElem().get(0);
+export const formValidate = (formEl) => {
formEl.classList.remove('hide-errors');
formEl.classList.add('show-warnings');
};
@@ -61,9 +67,24 @@ export const decorateURL = (destination, baseURL = window.location) => {
return null;
};
-export const formSuccess = (form) => {
- const formEl = form.getFormElem().get(0);
- const parentModal = formEl.closest('.dialog-modal');
+const setPreference = (key = '', value = '') => {
+ if (!value || !key.includes('.')) return;
+ const keyParts = key.split('.');
+ const lastKey = keyParts.pop();
+ const formDataObject = keyParts.reduce((obj, part) => {
+ obj[part] = obj[part] || {};
+ return obj[part];
+ }, window.mcz_marketoForm_pref);
+ formDataObject[lastKey] = value;
+};
+
+export const setPreferences = (formData) => {
+ window.mcz_marketoForm_pref = window.mcz_marketoForm_pref || {};
+ Object.entries(formData).forEach(([key, value]) => setPreference(key, value));
+};
+
+export const formSuccess = (formEl, formData) => {
+ const parentModal = formEl?.closest('.dialog-modal');
const mktoSubmit = new Event('mktoSubmit');
window.dispatchEvent(mktoSubmit);
@@ -76,10 +97,23 @@ export const formSuccess = (form) => {
return false;
}
- return true;
+ if (formData?.[SUCCESS_TYPE] !== 'section') return true;
+
+ try {
+ const section = formData[SUCCESS_SECTION].toLowerCase().replaceAll(' ', '-');
+ const success = document.querySelector(`.section.${section}`);
+ success.classList.remove('hide-block');
+ success.scrollIntoView({ behavior: 'smooth' });
+ setPreference(SUCCESS_TYPE, 'message');
+ } catch (e) {
+ /* c8 ignore next 2 */
+ window.lana?.log('Error showing Marketo success section', { tags: 'errorType=warn,module=marketo' });
+ }
+
+ return false;
};
-const readyForm = (form) => {
+const readyForm = (form, formData) => {
const formEl = form.getFormElem().get(0);
const isDesktop = matchMedia('(min-width: 900px)');
@@ -95,41 +129,27 @@ const readyForm = (form) => {
const offsetPosition = targetPosition + window.pageYOffset - pageTop - window.innerHeight / 2;
window.scrollTo(0, offsetPosition);
}, true);
- form.onValidate(() => formValidate(form));
- form.onSuccess(() => formSuccess(form));
-};
-
-const setPreference = (key, value) => {
- if (value && key?.includes('.')) {
- const keyParts = key.split('.');
- const lastKey = keyParts.pop();
- const formDataObject = keyParts.reduce((obj, part) => {
- obj[part] = obj[part] || {};
- return obj[part];
- }, window.mcz_marketoForm_pref);
- formDataObject[lastKey] = value;
- }
-};
-
-export const setPreferences = (formData) => {
- window.mcz_marketoForm_pref = window.mcz_marketoForm_pref || {};
- Object.entries(formData).forEach(([key, value]) => setPreference(key, value));
+ form.onValidate(() => formValidate(formEl));
+ form.onSuccess(() => formSuccess(formEl, formData));
};
export const loadMarketo = (el, formData) => {
const baseURL = formData[BASE_URL];
+ const munchkinID = formData[MUNCHKIN_ID];
+ const formID = formData[FORM_ID];
loadScript(`https://${baseURL}/js/forms2/js/forms2.min.js`)
.then(() => {
const { MktoForms2 } = window;
if (!MktoForms2) throw new Error('Marketo forms not loaded');
- MktoForms2.loadForm(`//${baseURL}`, formData[MUNCHKIN_ID], formData[FORM_ID]);
+ MktoForms2.loadForm(`//${baseURL}`, munchkinID, formID);
MktoForms2.whenReady((form) => { readyForm(form, formData); });
})
.catch(() => {
- /* c8 ignore next */
+ /* c8 ignore next 2 */
el.style.display = 'none';
+ window.lana?.log(`Error loading Marketo form for ${munchkinID}_${formID}`, { tags: 'errorType=error,module=marketo' });
});
};
@@ -137,7 +157,6 @@ export default function init(el) {
const children = Array.from(el.querySelectorAll(':scope > div'));
const encodedConfigDiv = children.shift();
const link = encodedConfigDiv.querySelector('a');
- let formData = {};
if (!link?.href) {
el.style.display = 'none';
@@ -145,8 +164,7 @@ export default function init(el) {
}
const encodedConfig = link.href.split('#')[1];
-
- formData = parseEncodedConfig(encodedConfig);
+ const formData = parseEncodedConfig(encodedConfig);
children.forEach((element) => {
const key = element.children[0]?.textContent.trim().toLowerCase().replaceAll(' ', '-');
@@ -168,13 +186,12 @@ export default function init(el) {
return;
}
- if (formData['form.success.content']) {
- const destinationUrl = decorateURL(formData['form.success.content']);
+ formData[SUCCESS_TYPE] = formData[SUCCESS_TYPE] || 'redirect';
- if (destinationUrl) {
- formData['form.success.type'] = 'redirect';
- formData['form.success.content'] = destinationUrl;
- }
+ if (formData[SUCCESS_TYPE] === 'redirect') {
+ const destinationUrl = decorateURL(formData[SUCCESS_CONTENT]);
+
+ if (destinationUrl) formData[SUCCESS_CONTENT] = destinationUrl;
}
setPreferences(formData);
diff --git a/libs/blocks/merch/merch.js b/libs/blocks/merch/merch.js
index fc0ce27410..138fbbce71 100644
--- a/libs/blocks/merch/merch.js
+++ b/libs/blocks/merch/merch.js
@@ -192,28 +192,48 @@ export async function fetchCheckoutLinkConfigs(base = '') {
?? fetch(`${base}${CHECKOUT_LINK_CONFIG_PATH}`).catch((e) => {
log?.error('Failed to fetch checkout link configs', e);
}).then((mappings) => {
- if (!mappings?.ok) return undefined;
+ if (!mappings?.ok) return { data: [] };
return mappings.json();
});
return fetchCheckoutLinkConfigs.promise;
}
-export async function getCheckoutLinkConfig(productFamily) {
+export async function getCheckoutLinkConfig(productFamily, productCode, paCode) {
let { base } = getConfig();
if (/\.page$/.test(document.location.origin)) {
/* c8 ignore next 2 */
base = base.replace('.live', '.page');
}
const checkoutLinkConfigs = await fetchCheckoutLinkConfigs(base);
+ if (!checkoutLinkConfigs.data.length) return undefined;
const { locale: { region } } = getConfig();
- const productFamilyConfigs = checkoutLinkConfigs.data?.filter(
- ({ [NAME_PRODUCT_FAMILY]: mappingProductFamily }) => mappingProductFamily === productFamily,
- );
- if (productFamilyConfigs.length === 0) return undefined;
- const checkoutLinkConfig = productFamilyConfigs.find(
+
+ const {
+ paCodeConfigs,
+ productCodeConfigs,
+ productFamilyConfigs,
+ } = checkoutLinkConfigs.data.reduce((acc, config) => {
+ if (config[NAME_PRODUCT_FAMILY] === paCode) {
+ acc.paCodeConfigs.push(config);
+ } else if (config[NAME_PRODUCT_FAMILY] === productCode) {
+ acc.productCodeConfigs.push(config);
+ } else if (config[NAME_PRODUCT_FAMILY] === productFamily) {
+ acc.productFamilyConfigs.push(config);
+ }
+ return acc;
+ }, { paCodeConfigs: [], productCodeConfigs: [], productFamilyConfigs: [] });
+
+ // helps to fallback to product family config
+ // if no locale specific config is found below.
+ const productCheckoutLinkConfigs = [
+ ...paCodeConfigs, ...productCodeConfigs, ...productFamilyConfigs,
+ ];
+
+ if (!productCheckoutLinkConfigs.length) return undefined;
+ const checkoutLinkConfig = productCheckoutLinkConfigs.find(
({ [NAME_LOCALE]: locale }) => locale === '',
);
- const checkoutLinkConfigOverride = productFamilyConfigs.find(
+ const checkoutLinkConfigOverride = productCheckoutLinkConfigs.find(
({ [NAME_LOCALE]: locale }) => locale === region,
) ?? {};
const overrides = Object.fromEntries(
@@ -231,14 +251,22 @@ export async function getCheckoutLinkConfig(productFamily) {
export async function getDownloadAction(
options,
imsSignedInPromise,
- [{ offerType, productArrangement: { productFamily: offerFamily } = {} }],
+ [{
+ offerType,
+ productArrangementCode,
+ productArrangement: { productCode, productFamily: offerFamily } = {},
+ }],
) {
if (options.entitlement !== true) return undefined;
const loggedIn = await imsSignedInPromise;
if (!loggedIn) return undefined;
const entitlements = await fetchEntitlements();
if (!entitlements?.length) return undefined;
- const checkoutLinkConfig = await getCheckoutLinkConfig(offerFamily);
+ const checkoutLinkConfig = await getCheckoutLinkConfig(
+ offerFamily,
+ productCode,
+ productArrangementCode,
+ );
if (!checkoutLinkConfig?.DOWNLOAD_URL) return undefined;
const offer = entitlements.find((
{ offer: { product_arrangement: { family: subscriptionFamily } } },
@@ -355,9 +383,17 @@ export async function openModal(e, url, offerType) {
}
export async function getModalAction(offers, options) {
- const [{ offerType, productArrangement: { productFamily: offerFamily } = {} }] = offers ?? [{}];
+ const [{
+ offerType,
+ productArrangementCode,
+ productArrangement: { productCode, productFamily: offerFamily } = {},
+ }] = offers ?? [{}];
if (options.modal !== true) return undefined;
- const checkoutLinkConfig = await getCheckoutLinkConfig(offerFamily);
+ const checkoutLinkConfig = await getCheckoutLinkConfig(
+ offerFamily,
+ productCode,
+ productArrangementCode,
+ );
if (!checkoutLinkConfig) return undefined;
const columnName = (offerType === OFFER_TYPE_TRIAL) ? FREE_TRIAL_PATH : BUY_NOW_PATH;
let url = checkoutLinkConfig[columnName];
diff --git a/libs/features/personalization/personalization.js b/libs/features/personalization/personalization.js
index 66d5936c15..4a092127b4 100644
--- a/libs/features/personalization/personalization.js
+++ b/libs/features/personalization/personalization.js
@@ -169,21 +169,19 @@ const fetchData = async (url, type = DATA_TYPE.JSON) => {
return null;
};
-const getBlockProps = (fVal) => {
+const getBlockProps = (fVal, miloLibs, origin) => {
let val = fVal;
if (val?.includes('\\')) val = val?.split('\\').join('/');
if (!val?.startsWith('/')) val = `/${val}`;
const blockSelector = val?.split('/').pop();
- const { origin } = PAGE_URL;
- if (origin.includes('.hlx.') || origin.includes('localhost')) {
- if (val.startsWith('/libs/')) {
- /* c8 ignore next 2 */
- const { miloLibs, codeRoot } = getConfig();
- val = `${miloLibs || codeRoot}${val.replace('/libs', '')}`;
- } else {
- val = `${origin}${val}`;
- }
+
+ if (val.startsWith('/libs/')) {
+ /* c8 ignore next 1 */
+ val = `${miloLibs}${val.replace('/libs', '')}`;
+ } else {
+ val = `${origin}${val}`;
}
+
return { blockSelector, blockTarget: val };
};
@@ -457,6 +455,7 @@ const getVariantInfo = (line, variantNames, variants, manifestPath, manifestOver
if (pageFilter && !matchGlob(pageFilter, new URL(window.location).pathname)) return;
if (!config.mep?.preview) manifestId = false;
+ const { origin } = PAGE_URL;
variantNames.forEach((vn) => {
const targetManifestId = vn.startsWith(TARGET_EXP_PREFIX) ? targetId : false;
if (!line[vn] || line[vn].toLowerCase() === 'false') return;
@@ -483,7 +482,7 @@ const getVariantInfo = (line, variantNames, variants, manifestPath, manifestOver
variants[vn][action] = variants[vn][action] || [];
if (action === 'useblockcode') {
- const { blockSelector, blockTarget } = getBlockProps(line[vn]);
+ const { blockSelector, blockTarget } = getBlockProps(line[vn], config.miloLibs, origin);
variants[vn][action].push({
selector: blockSelector,
val: blockTarget,
@@ -578,20 +577,26 @@ const checkForParamMatch = (paramStr) => {
return false;
};
+function trimNames(arr) {
+ return arr.map((v) => v.trim()).filter(Boolean);
+}
+export function buildVariantInfo(variantNames) {
+ return variantNames.reduce((acc, name) => {
+ let nameArr = [name];
+ if (!name.startsWith(TARGET_EXP_PREFIX)) nameArr = name.split(',');
+ acc[name] = trimNames(nameArr);
+ acc.allNames = [...acc.allNames, ...trimNames(name.split(/[,&]|\bnot\b/))];
+ return acc;
+ }, { allNames: [] });
+}
+
async function getPersonalizationVariant(manifestPath, variantNames = [], variantLabel = null) {
const config = getConfig();
if (config.mep?.variantOverride?.[manifestPath]) {
return config.mep.variantOverride[manifestPath];
}
- const variantInfo = variantNames.reduce((acc, name) => {
- let nameArr = [name];
- if (!name.startsWith(TARGET_EXP_PREFIX)) nameArr = name.split(',');
- const vNames = nameArr.map((v) => v.trim()).filter(Boolean);
- acc[name] = vNames;
- acc.allNames = [...acc.allNames, ...vNames];
- return acc;
- }, { allNames: [] });
+ const variantInfo = buildVariantInfo(variantNames);
const entitlementKeys = Object.values(await getEntitlementMap());
const hasEntitlementTag = entitlementKeys.some((tag) => variantInfo.allNames.includes(tag));
diff --git a/libs/features/spectrum-web-components/dist/icons-workflow.js b/libs/features/spectrum-web-components/dist/icons-workflow.js
index a46140ed29..7006fc8758 100644
--- a/libs/features/spectrum-web-components/dist/icons-workflow.js
+++ b/libs/features/spectrum-web-components/dist/icons-workflow.js
@@ -1,7 +1,7 @@
/* eslint-disable */
/* Generated by Milo */
-import{html as C}from"/libs/features/spectrum-web-components/dist/base.js";import{IconBase as L}from"/libs/features/spectrum-web-components/dist/icon.js";var c,i=function(t,...e){return c?c(t,...e):e.reduce((r,o,$)=>r+o+t[$+1],t[0])},a=t=>{c=t};var f=({width:t=24,height:e=24,hidden:r=!1,title:o="Alert"}={})=>i``;var s=class extends L{render(){return a(C),f({hidden:!this.label,title:this.label})}};import{defineElement as b}from"/libs/features/spectrum-web-components/dist/base.js";b("sp-icon-alert",s);import{html as I}from"/libs/features/spectrum-web-components/dist/base.js";import{IconBase as B}from"/libs/features/spectrum-web-components/dist/icon.js";var g=({width:t=24,height:e=24,hidden:r=!1,title:o="Help"}={})=>i`
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec cursus mi id tincidunt pretium. Praesent a porta ex. Etiam eu metus urna. Etiam vulputate nibh nisi, sed gravida diam dictum id. Cras et justo metus. Morbi consectetur @@ -89,15 +98,28 @@