Skip to content

Commit

Permalink
Standalone GNav for Non-Milo Consumers (#2669)
Browse files Browse the repository at this point in the history
* Adding configuration for header component

* Adding test cases

* Adding css changes

* Updated for css

* Setting the origin to federal

* Removing promise array

* Adding redirect uri in meta

* Updating meta insert function

* Lint fix

* Making error message descriptive

---------

Co-authored-by: Snehal Sonawane <sonawane@Snehals-MacBook-Pro.local>
  • Loading branch information
bandana147 and Snehal Sonawane authored Aug 8, 2024
1 parent ccb9704 commit aea0827
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 33 deletions.
24 changes: 20 additions & 4 deletions libs/navigation/bootstrapper.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
export default async function bootstrapBlock(miloConfigs, blockConfig) {
const { miloLibs } = miloConfigs;
export default async function bootstrapBlock(miloLibs, blockConfig) {
const { name, targetEl } = blockConfig;
const { getConfig, setConfig, createTag, loadLink, loadScript } = await import(`${miloLibs}/utils/utils.js`);
setConfig({ ...miloConfigs });
const { getConfig, createTag, loadLink, loadScript } = await import(`${miloLibs}/utils/utils.js`);
const { default: initBlock } = await import(`${miloLibs}/blocks/${name}/${name}.js`);

const styles = [`${miloLibs}/blocks/${name}/${name}.css`, `${miloLibs}/navigation/navigation.css`];
Expand All @@ -12,6 +10,24 @@ export default async function bootstrapBlock(miloConfigs, blockConfig) {
const block = createTag(targetEl, { class: name });
document.body[blockConfig.appendType](block);
}
// Configure Unav components and redirect uri
if (blockConfig.targetEl === 'header') {
const metaTags = [
{ key: 'unavComponents', name: 'universal-nav' },
{ key: 'redirect', name: 'adobe-home-redirect' },
];
metaTags.forEach((tag) => {
const { key } = tag;
if (blockConfig[key]) {
const metaTag = createTag('meta', {
name: tag.name,
content: blockConfig[key],
});
document.head.append(metaTag);
}
});
}

initBlock(document.querySelector(targetEl));
if (blockConfig.targetEl === 'footer') {
const { loadPrivacy } = await import(`${miloLibs}/scripts/delayed.js`);
Expand Down
15 changes: 12 additions & 3 deletions libs/navigation/navigation.css
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
/* Extracting the essential styles required for rendering the component independently */
.global-footer, .dialog-modal {
.global-navigation, .global-footer, .dialog-modal {
font-family: 'Adobe Clean', adobe-clean, 'Trebuchet MS', sans-serif;
line-height: 27px;
color: #2c2c2c;
word-wrap: break-word;
-webkit-font-smoothing: antialiased;
}

.global-footer a, .dialog-modal a {
.global-navigation a, .global-footer a, .dialog-modal a {
text-decoration: none;
}

.dialog-modal a {
color: #035FE6;
}

.global-footer img {
.global-navigation img, .global-footer img {
max-width: 100%;
height: auto;
}

.global-navigation {
font-size: 18px;
}

header.global-navigation {
height: 64px;
visibility: hidden;
}
68 changes: 53 additions & 15 deletions libs/navigation/navigation.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,73 @@
const blockConfig = {
footer: {
const blockConfig = [
{
key: 'header',
name: 'global-navigation',
targetEl: 'header',
appendType: 'prepend',
params: ['imsClientId'],
},
{
key: 'footer',
name: 'global-footer',
targetEl: 'footer',
appendType: 'appendChild',
params: ['privacyId', 'privacyLoadDelay'],
},
};
];

const envMap = {
prod: 'https://www.adobe.com',
stage: 'https://www.stage.adobe.com',
qa: 'https://feds--milo--adobecom.hlx.page',
qa: 'https://gnav--milo--adobecom.hlx.page',
};

function getParamsConfigs(configs) {
return blockConfig.reduce((acc, block) => {
block.params.forEach((param) => {
const value = configs[block.key]?.[param];
if (value !== undefined) {
acc[param] = value;
}
});
return acc;
}, {});
}

export default async function loadBlock(configs, customLib) {
const { footer, locale, env = 'prod' } = configs || {};
const { header, footer, authoringPath, env = 'prod', locale = '' } = configs || {};
const branch = new URLSearchParams(window.location.search).get('navbranch');
const miloLibs = branch ? `https://${branch}--milo--adobecom.hlx.page` : customLib || envMap[env];

if (!header && !footer) {
console.error('Global navigation Error: header and footer configurations are missing.');
return;
}
// Relative path can't be used, as the script will run on consumer's app
const { default: bootstrapBlock } = await import(`${miloLibs}/libs/navigation/bootstrapper.js`);
const { default: locales } = await import(`${miloLibs}/libs/utils/locales.js`);
const [{ default: bootstrapBlock }, { default: locales }, { setConfig }] = await Promise.all([
import(`${miloLibs}/libs/navigation/bootstrapper.js`),
import(`${miloLibs}/libs/utils/locales.js`),
import(`${miloLibs}/libs/utils/utils.js`),
]);

const paramConfigs = getParamsConfigs(configs, miloLibs);
const clientConfig = {
origin: miloLibs,
origin: `https://main--federal--adobecom.hlx.${env === 'prod' ? 'live' : 'page'}`,
miloLibs: `${miloLibs}/libs`,
pathname: `/${locale || ''}`,
pathname: `/${locale}`,
locales: configs.locales || locales,
contentRoot: authoringPath || footer.authoringPath,
...paramConfigs,
};
if (footer) {
const { authoringPath, privacyId, privacyLoadDelay = 3000 } = footer;
blockConfig.delay = privacyLoadDelay;
bootstrapBlock({ ...clientConfig, contentRoot: authoringPath, privacyId }, blockConfig.footer);
}
setConfig(clientConfig);

blockConfig.forEach((block) => {
const configBlock = configs[block.key];
if (configBlock) {
bootstrapBlock(`${miloLibs}/libs`, {
...block,
...(block.key === 'header' && { unavComponents: configBlock.unavComponents, redirect: configBlock.redirect }),
});
}
});
}

window.loadNavigation = loadBlock;
31 changes: 21 additions & 10 deletions test/navigation/bootstrapper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@ import { stub, useFakeTimers, restore } from 'sinon';
import loadBlock from '../../libs/navigation/bootstrapper.js';
import fetchedFooter from '../blocks/global-footer/mocks/fetched-footer.js';
import placeholders from '../blocks/global-navigation/mocks/placeholders.js';
import { setConfig } from '../../libs/utils/utils.js';

document.body.innerHTML = await readFile({ path: './mocks/body.html' });

const blockConfig = {
name: 'global-footer',
targetEl: 'footer',
appendType: 'append',
footer: { authoringPath: '/federal/home', privacyLoadDelay: 0 },
footer: {
name: 'global-footer',
targetEl: 'footer',
appendType: 'append',
},
header: {
name: 'global-navigation',
targetEl: 'header',
appendType: 'prepend',
unavComponents: 'profile',
},
};

const miloConfigs = {
origin: 'https://feds--milo--adobecom.hlx.page',
miloLibs: 'http://localhost:2000/libs',
pathname: '/',
};
const miloLibs = 'http://localhost:2000/libs';

const mockRes = ({ payload, status = 200, ok = true } = {}) => new Promise((resolve) => {
resolve({
Expand All @@ -43,14 +47,15 @@ describe('Bootstrapper', async () => {
if (url.includes('/footer.plain.html')) return mockRes({ payload: await readFile({ path: '../blocks/region-nav/mocks/regions.html' }) });
return null;
});
setConfig({ miloLibs, contentRoot: '/federal/dev' });
});

afterEach(() => {
restore();
});

it('Renders the footer block', async () => {
await loadBlock(miloConfigs, blockConfig);
await loadBlock(miloLibs, blockConfig.footer);
const clock = useFakeTimers({
toFake: ['setTimeout'],
shouldAdvanceTime: true,
Expand All @@ -59,4 +64,10 @@ describe('Bootstrapper', async () => {
const el = document.getElementsByTagName('footer');
expect(el).to.exist;
});

it('Renders the header block', async () => {
await loadBlock(miloLibs, blockConfig.header);
const el = document.getElementsByTagName('header');
expect(el).to.exist;
});
});
17 changes: 16 additions & 1 deletion test/navigation/navigation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,23 @@ document.body.innerHTML = await readFile({ path: './mocks/body.html' });

describe('Navigation component', async () => {
it('Renders the footer block', async () => {
await loadBlock({ footer: { authoringPath: '/federal/home' }, env: 'qa' }, 'http://localhost:2000');
await loadBlock({ authoringPath: '/federal/dev', footer: { privacyId: '12343' }, env: 'qa' }, 'http://localhost:2000');
const el = document.getElementsByTagName('footer');
expect(el).to.exist;
});

it('Renders the header block', async () => {
await loadBlock({ authoringPath: '/federal/dev', header: { imsClientId: 'fedsmilo' }, env: 'qa' }, 'http://localhost:2000');
const el = document.getElementsByTagName('header');
expect(el).to.exist;
});

it('Does not render either header or footer if not found in configs', async () => {
document.body.innerHTML = await readFile({ path: './mocks/body.html' });
await loadBlock({ authoringPath: '/federal/dev', env: 'qa' }, 'http://localhost:2000');
const header = document.getElementsByTagName('header');
const footer = document.getElementsByTagName('footer');
expect(header).to.be.empty;
expect(footer).to.be.empty;
});
});

0 comments on commit aea0827

Please sign in to comment.