UNPKG

@websolutespa/payload-plugin-bowl

Version:

Bowl PayloadCms plugin of the BOM Repository

246 lines (245 loc) 8.9 kB
import { MenuCategoryStrategy, asCategoryId, isObject, uuidv4 } from '@websolutespa/bom-core'; import { filterRoutes } from '../api/utils'; export const MAX_INT = 1000000000000; // 9007199254740991 function makeCategoryMenuItem_(item, category) { const id = item.id || uuidv4(); const title = item.customTitle || category.title || ''; const abstract = item.abstract || undefined; const customClass = item.customClass || undefined; const media = item.media || category.media; const items = []; return category.isHidden ? { type: 'group', id, title, abstract, media, customClass, items } : { type: 'category', category: category.id, id, href: '', title, abstract, media, customClass, items }; } export function decorateMenuCategory_(item, categories, routes, market, depth = 0) { const strategy = item.strategy || MenuCategoryStrategy.Default; const categoryId = asCategoryId(item.category); // find category const category = categoryId ? categories.find((x)=>x.id === categoryId) : undefined; if (category) { const decoratedItem = makeCategoryMenuItem_(item, category); if (!category.isHidden) { const route = routes.find((route)=>route.isDefault && route.resolvedCategory === category.id); if (route) { decoratedItem.href = route.id; if (!decoratedItem.media) { decoratedItem.media = route.media; } } } // checking for max depth recursion let maxDepth = item.maxDepth; if (typeof maxDepth === 'number') { if (depth > maxDepth) { return decoratedItem; } maxDepth--; } // search child categories const childCategories = (category.id ? categories.filter((x)=>asCategoryId(x.category) === category.id) : []).filter((x)=>{ switch(strategy){ case MenuCategoryStrategy.ExcludeHidden: return Boolean(x.isHidden) === false; case MenuCategoryStrategy.Default: return true; } }); // sort child categories childCategories.sort((a, b)=>{ return (a.order || MAX_INT) - (b.order || MAX_INT); }); // define sub strategy (!!! todo) const subStrategy = strategy; // decorate child categories const childCategoryItems = childCategories.map((c)=>decorateMenuCategory_({ id: c.id, type: 'category', category: c.id, maxDepth, strategy: subStrategy, items: [] }, categories, routes, market, depth + 1)); // find child routes const childRoutes = routes.filter((route)=>{ switch(strategy){ case MenuCategoryStrategy.ExcludeHidden: return route.resolvedCategory === category.id && Boolean(route.isDefault) === false; case MenuCategoryStrategy.Default: return route.category === category.id && (category.isHidden || Boolean(route.isDefault) === false); } }); // sort child routes childRoutes.sort((a, b)=>{ return (a.order || MAX_INT) - (b.order || MAX_INT); }); // decorate child routes const childRouteItems = childRoutes.map((x)=>decorateMenuRoute_(x)); // filter items decoratedItem.items = [ ...childCategoryItems, ...childRouteItems ].filter((x)=>Boolean(x)); return decoratedItem; } // return unresolved category as group return { id: item.id || uuidv4(), type: 'group', title: item.customTitle || '', items: [] }; } export function decorateMenuGroup_(item, categories, routes, market) { const decoratedItem = { id: item.id, type: item.type, title: item.title, media: item.media, abstract: item.abstract, customClass: item.customClass, extra: item.extra, items: (item.items || []).filter((x)=>hasMarket(x, market)).map((x)=>decorateMenuItem_(x, categories, routes, market)) }; return decoratedItem; } export function decorateMenuLink_(item, categories, routes, market) { const decoratedItem = { id: item.id, type: item.type, title: item.title, href: item.href, target: item.target, media: item.media, abstract: item.abstract, customClass: item.customClass, extra: item.extra, items: (item.items || []).filter((x)=>hasMarket(x, market)).map((x)=>decorateMenuItem_(x, categories, routes, market)) }; return decoratedItem; } export function decorateMenuPage_(item, categories, routes, market) { const page = isObject(item.page.value) ? item.page.value : { id: item.page.value }; // console.log('decorateMenuPage_', page); const route = routes.find((x)=>x.schema === item.page.relationTo && x.page === page.id); // console.log('decorateMenuPage_', page, route); const schema = item.schema || item.page.relationTo; const decoratedItem = { type: item.type, schema, id: item.id, href: route?.id || '', page: route ? route.page : page.id, title: item.customTitle || page.title || route?.title || '', items: (item.items || []).filter((x)=>hasMarket(x, market)).map((x)=>decorateMenuItem_(x, categories, routes, market)) }; if (item.abstract) { decoratedItem.abstract = item.abstract; } if (item.extra) { decoratedItem.extra = item.extra; } if (item.customClass) { decoratedItem.customClass = item.customClass; } const media = item.media || page.media || route?.media; if (media) { decoratedItem.media = media; } // items?: IMenuItem[]; return decoratedItem; } export function decorateMenuRoute_(item) { const decoratedItem = { id: item.page, type: 'route', title: item.title, media: item.media, href: item.id, page: item.page, schema: item.schema, items: [] }; return decoratedItem; } export function decorateMenuItem_(item, categories, routes, market, depth = 0) { switch(item.type){ case 'category': return decorateMenuCategory_(item, categories, routes, market, depth); case 'group': return decorateMenuGroup_(item, categories, routes, market); case 'link': return decorateMenuLink_(item, categories, routes, market); case 'page': return decorateMenuPage_(item, categories, routes, market); default: // eslint-disable-next-line no-case-declarations const { blockType, ...rest } = item; return { ...rest, type: blockType }; } } export function decorateNavItem_(item, categories, routes, market, depth = 0) { switch(item.type){ case 'category': return decorateMenuCategory_(item, categories, routes, market, depth); case 'page': if (Array.isArray(item.page.value)) { return item.page.value.map((x)=>{ return decorateMenuPage_({ ...item, page: { ...item.page, value: x } }, categories, routes, market); }); } return decorateMenuPage_(item, categories, routes, market); } } // !!! todo how to handle unknown types? export function hasMarket(item, market) { return market === 'all' ? true : Array.isArray(item.markets) && item.markets.length > 0 ? item.markets.includes(market) : true; } export async function decorateMenu_(item, context) { // console.log('decorateMenu_'); const decoratedItem = { id: item.id, items: [] }; const { market, locale, markets, locales, routes, categories } = context; // check if language is enabled if (!locales.includes(locale) && locale !== 'all') { return decoratedItem; } // check if market is enabled if (!markets.includes(market) && market !== 'all') { return decoratedItem; } const filteredRoutes = filterRoutes(routes, market, locale); // check if market is enabled decoratedItem.items = (item.items || []).filter((x)=>hasMarket(x, market)).map((x)=>decorateMenuItem_(x, categories, filteredRoutes, market)); return decoratedItem; } //# sourceMappingURL=menu.js.map