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

MWPW-157147: Dynamic Nav Status #2918

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
be90c7d
[Release] Stage to Main (#2359)
milo-pr-merge[bot] Jun 3, 2024
d9af238
[Release] Stage to Main (#2409)
milo-pr-merge[bot] Jun 4, 2024
b07f1a5
[Release] Stage to Main (#2414)
milo-pr-merge[bot] Jun 5, 2024
e5bff30
[Release] Stage to Main (#2423)
milo-pr-merge[bot] Jun 6, 2024
81d0085
[Release] Stage to Main (#2432)
milo-pr-merge[bot] Jun 10, 2024
e8300af
[Release] Stage to Main (#2447)
milo-pr-merge[bot] Jun 11, 2024
2350bd0
[Release] Stage to Main (#2462)
milo-pr-merge[bot] Jun 12, 2024
931fa67
[Release] Stage to Main (#2470)
milo-pr-merge[bot] Jun 13, 2024
ead382f
[Release] Stage to Main (#2472)
milo-pr-merge[bot] Jun 17, 2024
ddbdf7a
[Release] Stage to Main (#2479)
milo-pr-merge[bot] Jun 18, 2024
02bf1a6
[Release] Stage to Main (#2482)
milo-pr-merge[bot] Jun 19, 2024
f6fc4bf
[Release] Stage to Main (#2489)
milo-pr-merge[bot] Jun 20, 2024
47aaef0
[Release] Stage to Main (#2495)
milo-pr-merge[bot] Jun 24, 2024
03578fb
[Release] Stage to Main (#2503)
milo-pr-merge[bot] Jun 25, 2024
32f61f0
[Release] Stage to Main (#2515)
milo-pr-merge[bot] Jun 26, 2024
2217784
[Release] Stage to Main (#2520)
milo-pr-merge[bot] Jun 27, 2024
862fdab
[Release] Stage to Main (#2528)
milo-pr-merge[bot] Jul 8, 2024
88577c7
[Release] Stage to Main (#2540)
milo-pr-merge[bot] Jul 10, 2024
830f7e1
[Release] Stage to Main (#2556)
milo-pr-merge[bot] Jul 15, 2024
bc210e6
[Release] Stage to Main (#2568)
milo-pr-merge[bot] Jul 16, 2024
04e211c
[Release] Stage to Main (#2571)
milo-pr-merge[bot] Jul 17, 2024
4e99424
[Release] Stage to Main (#2580)
milo-pr-merge[bot] Jul 18, 2024
61f8c81
[Release] Stage to Main (#2592)
milo-pr-merge[bot] Jul 22, 2024
3365940
[Release] Stage to Main (#2602)
milo-pr-merge[bot] Jul 23, 2024
e89908c
[Release] Stage to Main (#2609)
milo-pr-merge[bot] Jul 24, 2024
f551e5b
[Release] Stage to Main (#2617)
milo-pr-merge[bot] Jul 25, 2024
5028ef5
[Release] Stage to Main (#2629)
milo-pr-merge[bot] Jul 29, 2024
0073337
[Release] Stage to Main (#2641)
milo-pr-merge[bot] Jul 30, 2024
c3371ce
[Release] Stage to Main (#2648)
milo-pr-merge[bot] Jul 31, 2024
8f6bc8f
[Release] Stage to Main (#2666)
milo-pr-merge[bot] Aug 5, 2024
498b7c8
[Release] Stage to Main (#2688)
milo-pr-merge[bot] Aug 6, 2024
5401829
[Release] Stage to Main (#2697)
milo-pr-merge[bot] Aug 7, 2024
833abd4
[Release] Stage to Main (#2701)
milo-pr-merge[bot] Aug 8, 2024
3abbe4d
[Release] Stage to Main (#2716)
milo-pr-merge[bot] Aug 12, 2024
0b80fa1
[Release] Stage to Main (#2722)
milo-pr-merge[bot] Aug 13, 2024
baef0d5
[Release] Stage to Main (#2734)
milo-pr-merge[bot] Aug 14, 2024
53f37de
[Release] Stage to Main (#2742)
milo-pr-merge[bot] Aug 19, 2024
7dbef3a
[Release] Stage to Main (#2756)
milo-pr-merge[bot] Aug 20, 2024
c06c15d
[Release] Stage to Main (#2766)
milo-pr-merge[bot] Aug 21, 2024
eeddca4
[Release] Stage to Main (#2775)
milo-pr-merge[bot] Sep 2, 2024
91afbee
[Release] Stage to Main (#2811)
milo-pr-merge[bot] Sep 3, 2024
95fb526
[Release] Stage to Main (#2821)
milo-pr-merge[bot] Sep 5, 2024
c8d526f
[Release] Stage to Main (#2842)
milo-pr-merge[bot] Sep 9, 2024
65fb7b9
Adding the preview feature, may need to rename some files and still n…
JasonHowellSlavin Sep 17, 2024
2dec4d7
CSS adjustments
JasonHowellSlavin Sep 17, 2024
112e3e8
Additional CSS adjustments
JasonHowellSlavin Sep 17, 2024
c874bc4
JS fixes for CLS
JasonHowellSlavin Sep 17, 2024
7be732d
Race condition fixes, CSS touchups, text from PM
JasonHowellSlavin Sep 18, 2024
c981c47
Syntax error fix
JasonHowellSlavin Sep 18, 2024
bb19fd2
CSS loading placement and small CSS changes
JasonHowellSlavin Sep 18, 2024
36c2a1e
Final touches, ready for code review
JasonHowellSlavin Sep 19, 2024
13c5210
Renaming preview to status, fixing unneeded change in test
JasonHowellSlavin Sep 19, 2024
bd56dcf
Changing preview to status in utils
JasonHowellSlavin Sep 19, 2024
666aed4
Changing name in case of issue
JasonHowellSlavin Sep 19, 2024
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
2 changes: 1 addition & 1 deletion libs/blocks/global-navigation/global-navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,7 @@ const getSource = async () => {
const { locale, dynamicNavKey } = getConfig();
let url = getMetadata('gnav-source') || `${locale.contentRoot}/gnav`;
if (dynamicNavKey) {
const { default: dynamicNav } = await import('../../features/dynamic-navigation.js');
const { default: dynamicNav } = await import('../../features/dynamic-navigation/dynamic-navigation.js');
url = dynamicNav(url, dynamicNavKey);
}
return url;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getMetadata } from '../utils/utils.js';
import { getMetadata } from '../../utils/utils.js';

function isDynamicNavDisabled() {
export function isDynamicNavDisabled() {
const dynamicNavDisableValues = getMetadata('dynamic-nav-disable');
if (!dynamicNavDisableValues) return false;

Expand Down
173 changes: 173 additions & 0 deletions libs/features/dynamic-navigation/status.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
.dynamic-nav-status {
border: 2px solid white;
border-radius: 32px;
color: #eee;
font-size: 16px;
padding: 12px 24px;
cursor: pointer;
display: flex;
align-items: center;
margin: 12px;
position: relative;
}

.dynamic-nav-status .title {
display: flex;
}

.dynamic-nav-status.active {
background-color: #280;
}

.dynamic-nav-status.enabled {
background-color: #ec4;
}

.dynamic-nav-status.inactive {
background-color: #e20;
}

.dns-badge {
border: 2px solid white;
border-radius: 32px;
background-color: transparent;
box-sizing: border-box;
color: #eee;
padding: 8px;
height: 12px;
width: 12px;
margin: 4px 8px 4px 0;
cursor: pointer;
display: flex;
align-items: center;
position: relative;
}

.dns-badge::after {
content: '';
display: block;
box-sizing: border-box;
position: absolute;
width: 6px;
height: 6px;
border-top: 2px solid;
border-right: 2px solid;
transform: rotate(45deg);
left: 5px;
bottom: 5px;
transition-duration: 0.2s;
}

.dns-badge.dns-open::after{
transform: rotate(135deg);
transition-duration: 0.2s;
}

.dynamic-nav-status .hidden {
display: none;
}

.dynamic-nav-status.enabled .title,
.dynamic-nav-status.enabled .dns-badge {
color: var(--feds-color-hamburger);
border-color: var(--feds-color-hamburger);
}

.dynamic-nav-status .dns-close-container {
display: flex;
justify-content: flex-end;
width: 100%;
height: 10px;
padding: 2px;
}

.dynamic-nav-status .dns-close {
cursor: pointer;
display: block;
position: absolute;
border: 2px solid white;
border-radius: 32px;
background-color: transparent;
color: #eee;
height: 20px;
width: 20px;
top: 6px;
right: 6px;
box-sizing: border-box;
}

.dynamic-nav-status .dns-close::after {
content: 'x';
display: block;
box-sizing: border-box;
position: absolute;
width: 6px;
height: 6px;
left: 4px;
top: -8px;
font-size: 18px;
font-weight: 600;
}

.dynamic-nav-status .details {
position: absolute;
top: 60px;
right: 0;
background-color: #444;
min-width: 300px;
border-radius: 16px;
box-shadow: 0 0 10px #000;
font-size: 12px;
padding: 20px;
z-index: 1;
}

.dynamic-nav-status .details::before {
content: '';
width: 0;
height: 0;
position: absolute;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 15px solid #444;
top: -15px;
right: 75px;
rotate: 180deg;
}

.dynamic-nav-status p{
margin: 2px;
}

.dynamic-nav-status .details p {
font-weight: 600;
}

.dynamic-nav-status .details span {
font-weight: 300;
}

.dynamic-nav-status .details .additional-info {
border-bottom: 1px solid white;
}

.dynamic-nav-status .disable-values{
min-width: 100%;
}

.dynamic-nav-status .disable-values table {
border-collapse: collapse;
width: 100%;
}

.dynamic-nav-status .disable-values caption{
min-width: 100%;
text-align: left;
font-weight: 600;
}

.dynamic-nav-status .disable-values th,
.dynamic-nav-status .disable-values td {
border: 1px solid rgb(160 160 160);
padding: 8px 10px;
}
133 changes: 133 additions & 0 deletions libs/features/dynamic-navigation/status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { createTag, getConfig, getMetadata, loadStyle } from '../../utils/utils.js';
import { isDynamicNavDisabled } from './dynamic-navigation.js';

export const ACTIVE = 'active';
export const ENABLED = 'enabled';
export const INACTIVE = 'inactive';
export const tooltipInfo = {
active: 'Displayed in green, this status appears when a user is on an entry page or a page with the Dynamic Nav enabled, indicating that the nav is fully functioning.',
enabled: 'Displayed in yellow, this status indicates that the Dynamic Nav is set to "on," but the user has not yet visited an entry page.',
inactive: 'Displayed in red, this status indicates that the Dynamic Nav is either not configured or has been disabled.',
};

const getCurrentSource = (status, storageSource, authoredSource) => {
if (status === 'on') {
return storageSource || authoredSource;
}
return authoredSource;
};

const getStatus = (status, disabled, storageSource) => {
if (status === 'entry') return ACTIVE;

if (disabled) return INACTIVE;

if (status === 'on' && storageSource) return ACTIVE;

if (status === 'on' && !storageSource) return ENABLED;

return INACTIVE;
};

const processDisableValues = (arr, elem) => {
if (arr === null || arr === undefined || arr.length === 0) return;

const diableValueList = arr.split(',');
const table = createTag('table');

const tableDOM = `
<caption>Disable Values</caption>
<thead>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tbody>
</tbody>`;

table.innerHTML = tableDOM;
const tBody = table.querySelector('tbody');

diableValueList.forEach((pair) => {
const itemRow = createTag('tr');
const [key, value] = pair.split(';');
const keyElem = createTag('td');
const valElem = createTag('td');
keyElem.innerText = key;
valElem.innerText = value;

itemRow.append(keyElem, valElem);
tBody.append(itemRow);
});

elem.append(table);
};

const returnPath = (url) => {
if (!url.includes('https://')) return '';
const sourceUrl = new URL(url);
return sourceUrl.pathname;
};

const createStatusWidget = (dynamicNavKey) => {
const storedSource = window.sessionStorage.getItem('gnavSource');
const authoredSource = getMetadata('gnav-source') || 'Metadata not found: site gnav source';
const dynamicNavSetting = getMetadata('dynamic-nav');
const currentSource = getCurrentSource(dynamicNavSetting, storedSource, authoredSource);
const dynamicNavDisableValues = getMetadata('dynamic-nav-disable');
const status = getStatus(dynamicNavSetting, isDynamicNavDisabled(), storedSource);
const statusWidget = createTag('div', { class: 'dynamic-nav-status' });

statusWidget.innerHTML = `
<span class="title"><span class="dns-badge"></span>Dynamic Nav</span>
<section class="details hidden">
<span class="dns-close"></span>
<div class="message additional-info">
<p>Additional Info:
<span>${tooltipInfo[status]}</span>
</p>
</div>
<p class="status">Status: <span>${status}</span></p>
<p class="setting">Setting: <span>${dynamicNavSetting}</span></p>
<p class="consumer-key">Consumer key: <span>${dynamicNavKey}</span></p>
<div class="nav-source-info">
<p>Authored and stored source match: <span>${authoredSource === currentSource}</span></p>
<p>Authored Nav Source:
<span>${returnPath(authoredSource)}</span></p>
<p>Stored Nav Source:
<span>${returnPath(currentSource)}</span></p>
</div>
<div class="disable-values">
</div>
</section>
`;

processDisableValues(dynamicNavDisableValues, statusWidget.querySelector('.disable-values'));
statusWidget.classList.add(status);

statusWidget.addEventListener('click', () => {
statusWidget.querySelector('.details').classList.toggle('hidden');
statusWidget.querySelector('.dns-badge').classList.toggle('dns-open');
});

return statusWidget;
};

export default async function main() {
const { dynamicNavKey, miloLibs, codeRoot, env } = getConfig();
if (env?.name === 'prod') return;

loadStyle(`${miloLibs || `${codeRoot}/libs`}/features/dynamic-navigation/status.css`);

const statusWidget = createStatusWidget(dynamicNavKey);
const topNav = document.querySelector('.feds-topnav');
const fedsWrapper = document.querySelector('.feds-nav-wrapper');
const dnsClose = statusWidget.querySelector('.dns-close');

dnsClose.addEventListener('click', () => {
topNav.removeChild(statusWidget);
});

fedsWrapper.after(statusWidget);
}
4 changes: 4 additions & 0 deletions libs/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,10 @@ export async function loadDeferred(area, blocks, config) {
import('../features/personalization/preview.js')
.then(({ default: decoratePreviewMode }) => decoratePreviewMode());
}
if (config?.dynamicNavKey) {
const { default: loadDNStatus } = await import('../features/dynamic-navigation/status.js');
loadDNStatus();
}
}

function initSidekick() {
Expand Down
2 changes: 1 addition & 1 deletion test/features/dynamic-nav/dynamicNav.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { readFile } from '@web/test-runner-commands';
import { expect } from '@esm-bundle/chai';
import { setConfig } from '../../../libs/utils/utils.js';
import dynamicNav from '../../../libs/features/dynamic-navigation.js';
import dynamicNav from '../../../libs/features/dynamic-navigation/dynamic-navigation.js';

describe('Dynamic nav', () => {
beforeEach(() => {
Expand Down
9 changes: 9 additions & 0 deletions test/features/dynamic-nav/mocks/status.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<header>
<nav class="feds-topnav" aria-label="Main">
<div class="feds-brand-container">
</div>
<div class="feds-nav-wrapper" id="feds-nav-wrapper">
<div class="feds-nav"></div>
</div>
</nav>
</header>
Loading
Loading