Skip to content

Commit

Permalink
MWPW-132393 Catalog page (adobecom#161)
Browse files Browse the repository at this point in the history
* MWPW-136872 first draft for filter blocks (adobecom#107)
- using sidenav web component dep,
- using separate spectrum dep,
- introducing unit tests in CC
* MWPW_137257 sidenav block  (adobecom#118)
* MWPW-136866: index path config (adobecom#121)
for merch-cards block in Milo
* MWPW-132393: catalog layout
* update sidenav merch-cards integration
* update styles
* cleanup styles
* MWPW-137257 sidenav fixes (adobecom#122)

---------

Co-authored-by: ilyas Stéphane Türkben <isturkben@gmail.com>

* MWPW-134233: sidenav deeplink fix (adobecom#126)

* MWPW-134233: sidenav deeplink fix

* MWPW-134233: sidenav deeplink fix

* MWPW-137257 adapt values to taxonomy (adobecom#141)

- possibility to explicitally set order / and item, by adding list with last token of taxonomy,
- types to be displayed if navigation is multilevel,
- search text now based on first bold text

* MWPW-139915: catalog load swc from Milo (adobecom#149)

* MWPW-141104: Consume Milo SWC in the unit tests (adobecom#157)

* review comments

* gh action review comments

* re-set logs, with lana this time

* remove sidenav

---------

Co-authored-by: ilyas Stéphane Türkben <isturkben@gmail.com>
Co-authored-by: Ilyas Stéphane Türkben <tuerkben@adobe.com>
  • Loading branch information
3 people authored Jan 18, 2024
1 parent 18f936e commit 1cce586
Show file tree
Hide file tree
Showing 15 changed files with 10,263 additions and 997 deletions.
31 changes: 31 additions & 0 deletions creativecloud/blocks/catalog/catalog.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.catalog.app {
display: flex;
min-height: 400px;
justify-content: center;
}


@media screen and (min-width: 1200px) {
.catalog.app {
display: grid;
gap: 36px;
grid-template-columns: 240px auto;
min-height: 400px;
}

merch-sidenav {
min-width: 240px;
}
}

.catalog > merch-sidenav {
grid-column: 1 / span 1;
order: 0;
}

.catalog > merch-cards {
align-self: baseline;
grid-column: 2 / span 1;
order: 1;
padding: 0;
}
26 changes: 26 additions & 0 deletions creativecloud/blocks/catalog/catalog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-disable chai-friendly/no-unused-expressions */
import { getLibs } from '../../scripts/utils.js';

export default async function init(el) {
const miloLibs = getLibs();
import(`${miloLibs}/deps/lit-all.min.js`);
import(`${miloLibs}/blocks/merch-cards/merch-cards.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/theme.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/button.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/icons/checkmark.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/icons/chevron.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/help-text.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/icon.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/icons-ui.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/icons-workflow.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/menu.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/overlay.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/popover.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/reactive-controllers.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/search.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/shared.js`);
import(`${miloLibs}/features/spectrum-web-components/dist/textfield.js`);
el.classList.add('merch', 'app');
el.innerHTML = '';
return el;
}
1 change: 1 addition & 0 deletions creativecloud/blocks/sidenav/sidenav.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* sidenav styles */
169 changes: 169 additions & 0 deletions creativecloud/blocks/sidenav/sidenav.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import { createTag, localizeLink, getLibs } from '../../scripts/utils.js';

import '../../deps/merch-sidenav.js';

const CATEGORY_ID_PREFIX = 'categories/';
const TYPE_ID_PREFIX = 'types/';

const getIdLeaf = (id) => (id?.substring(id.lastIndexOf('/') + 1) || id);

const getCategories = (items, isMultilevel, mapCategories) => {
const configuration = { manageTabIndex: true };
if (isMultilevel) {
configuration.variant = 'multilevel';
}
const mapParents = [];
const tag = createTag('sp-sidenav', configuration);
const merchTag = createTag('merch-sidenav-list', { deeplink: 'category' });
merchTag.append(tag);
items.forEach((item) => {
if (item) {
let parent = tag;
const value = getIdLeaf(item.id);
// first token is type, second is parent category
const isParent = item.id.split('/').length <= 2;
const itemTag = createTag('sp-sidenav-item', { label: item.name, value });
if (isParent) {
mapParents[value] = itemTag;
tag.append(itemTag);
} else {
const parentId = getIdLeaf(item.id.substring(0, item.id.lastIndexOf('/')));
if (isMultilevel) {
if (!mapParents[parentId]) {
const parentItem = mapCategories[parentId];
if (parentItem) {
mapParents[parentId] = createTag('sp-sidenav-item', { label: parentItem.name, parentId });
tag.append(mapParents[parentId]);
}
}
parent = mapParents[parentId];
}
parent?.append(itemTag);
}
}
});
return merchTag;
};

const getTypes = (arrayTypes) => {
const tag = createTag('merch-sidenav-checkbox-group', { title: 'Types', deeplink: 'types' });
arrayTypes.forEach((item) => {
if (item.name?.length > 0) {
const checkbox = createTag('sp-checkbox', {
emphasized: '',
name: getIdLeaf(item.id),
});
checkbox.append(item.name);
tag.append(checkbox);
}
});
return tag;
};

const appendFilters = async (root, link, explicitCategoriesElt) => {
try {
const resp = await fetch(link);
if (resp.ok) {
const json = await resp.json();
const mapCategories = {};
let categoryValues = [];
const types = [];
json.data.forEach((item) => {
if (item.id?.startsWith(CATEGORY_ID_PREFIX)) {
const value = getIdLeaf(item.id);
mapCategories[value] = item;
categoryValues.push(value);
} else if (item.id?.startsWith(TYPE_ID_PREFIX)) {
types.push(item);
}
});
if (explicitCategoriesElt) {
categoryValues = Array.from(explicitCategoriesElt.querySelectorAll('li'))
.map((item) => item.textContent.trim().toLowerCase());
}
let shallowCategories = true;
if (categoryValues.length > 0) {
const items = categoryValues.map((value) => mapCategories[value]);
const parentValues = new Set(items.map((value) => value?.id.split('/')[1]));
// all parent will always be here without children,
// so shallow is considered below 2 parents
shallowCategories = parentValues.size <= 2;
const categoryTags = getCategories(items, !shallowCategories, mapCategories);
root.append(categoryTags);
}
if (!shallowCategories && types.length > 0) {
root.append(getTypes(types));
}
}
} catch (e) {
window.lana?.log(`unable to properly fetch sidenav data: ${e}`);
}
};

function appendSearch(rootNav, searchText) {
if (searchText) {
const spectrumSearch = createTag('sp-search', { placeholder: searchText });
const search = createTag('merch-search', { deeplink: 'search' });
search.append(spectrumSearch);
rootNav.append(search);
}
}

function appendResources(rootNav, resourceLink) {
const literals = resourceLink.textContent.split(':');
const title = literals[0].trim();
const tag = createTag('sp-sidenav', { manageTabIndex: true });
const merchTag = createTag('merch-sidenav-list', { title });
merchTag.append(tag);
const label = literals[1].trim();
const link = createTag('sp-sidenav-item', { href: resourceLink.href });
if (resourceLink.href && resourceLink.href.startsWith('http')) {
link.append(document.createTextNode(label));
const icon = createTag('sp-icon-link-out-light', { class: 'right', slot: 'icon' });
link.append(icon);
}
tag.append(link);
rootNav.append(merchTag);
}

export default async function init(el) {
const libs = getLibs();
await Promise.all([
import(`${libs}/features/spectrum-web-components/dist/theme.js`),
import(`${libs}/features/spectrum-web-components/dist/sidenav.js`),
import(`${libs}/features/spectrum-web-components/dist/search.js`),
import(`${libs}/features/spectrum-web-components/dist/checkbox.js`),
import(`${libs}/features/spectrum-web-components/dist/dialog.js`),
]);

const title = el.querySelector('h2')?.textContent.trim();
const rootNav = createTag('merch-sidenav', { title });
const searchText = el.querySelector('p > strong')?.textContent.trim();
appendSearch(rootNav, searchText);
// eslint-disable-next-line prefer-const
let [endpoint, resourcesLink] = el.querySelectorAll('a');
if (endpoint) {
endpoint = localizeLink(endpoint.textContent.trim(), null, true);
const explicitCategories = el.querySelector('ul');
await appendFilters(rootNav, endpoint, explicitCategories);
}
if (resourcesLink) {
appendResources(rootNav, resourcesLink);
}

const appContainer = document.querySelector('.merch.app');
if (appContainer) {
appContainer.appendChild(rootNav);
rootNav.updateComplete.then(() => {
el.remove();
const merchCards = appContainer.querySelector('merch-cards');
if (merchCards) {
merchCards.sidenav = merchCards.sidenav || rootNav;
merchCards.requestUpdate();
}
});
} else {
el.replaceWith(rootNav);
}
return rootNav;
}
Loading

0 comments on commit 1cce586

Please sign in to comment.